From 840daf70ff3f7c2c8e9cc0fae0037befcfa18edf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Nov 2014 20:14:04 +0100 Subject: fix a crash bug applyed on groups (bzr r13708.1.1) --- src/live_effects/effect.cpp | 3 ++- src/live_effects/lpe-copy_rotate.cpp | 11 +++++++---- src/live_effects/lpe-copy_rotate.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index e49a15dd0..0f4bdfaaa 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -112,7 +112,6 @@ const Util::EnumData LPETypeData[] = { {PATH_LENGTH, N_("Path length"), "path_length"}, {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"}, {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"}, - {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, @@ -153,6 +152,8 @@ const Util::EnumData LPETypeData[] = { {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, +/* 0.92 */ + {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index e466093d3..7e3f35f9d 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -76,11 +76,12 @@ LPECopyRotate::~LPECopyRotate() void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { - SPCurve const *curve = SP_SHAPE(lpeitem)->_curve; + using namespace Geom; - A = *(curve->first_point()); - B = *(curve->last_point()); + original_bbox(lpeitem); + Point A(boundingbox_X.min(), boundingbox_Y.middle()); + Point B(boundingbox_X.max(), boundingbox_Y.middle()); origin.param_setValue(A); dir = unit_vector(B - A); @@ -123,12 +124,14 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point) origin); path.appendNew(rot_pos); - + std::cout << rot_pos << "rot\n"; + std::cout << origin << "origin\n"; PathVector pathv; pathv.push_back(path); hp_vec.push_back(pathv); } + void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index ca7aa269c..c84889f57 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -16,6 +16,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/point.h" +#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { @@ -26,7 +27,7 @@ namespace CR { class KnotHolderEntityRotationAngle; } -class LPECopyRotate : public Effect { +class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); -- cgit v1.2.3 From 015ec174f96c7e0aa96f4bab17a2895b62f4c24c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 16 Nov 2014 20:47:41 +0100 Subject: 360 auto degree calculation check (bzr r13708.1.2) --- src/live_effects/lpe-copy_rotate.cpp | 52 +++++++----------------------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 10 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 7e3f35f9d..51787e292 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -38,12 +38,6 @@ public: virtual Geom::Point knot_get() const; }; -class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { -public: - KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; } // namespace CR @@ -52,6 +46,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), + copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) { @@ -59,6 +54,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: + registerParameter( dynamic_cast(&copiesTo360) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -82,6 +78,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) Point A(boundingbox_X.min(), boundingbox_Y.middle()); Point B(boundingbox_X.max(), boundingbox_Y.middle()); + Point C(boundingbox_X.middle(), boundingbox_Y.middle()); origin.param_setValue(A); dir = unit_vector(B - A); @@ -96,7 +93,11 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle)) * dist_angle_handle; + double rotation_angle_end = rotation_angle; + if(copiesTo360){ + rotation_angle_end = 360.0/(double)num_copies; + } + rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; A = pwd2_in.firstValue(); B = pwd2_in.lastValue(); @@ -108,7 +109,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p for (int i = 0; i < num_copies; ++i) { // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-deg_to_rad(rotation_angle_end * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } @@ -124,8 +125,6 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point) origin); path.appendNew(rot_pos); - std::cout << rot_pos << "rot\n"; - std::cout << origin << "origin\n"; PathVector pathv; pathv.push_back(path); hp_vec.push_back(pathv); @@ -139,12 +138,6 @@ void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *des _("Adjust the starting angle") ); knotholder->add(e); } - { - KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the rotation angle") ); - knotholder->add(e); - } }; namespace CR { @@ -171,26 +164,6 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } -void -KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) -{ - LPECopyRotate* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - lpe->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); - if (state & GDK_SHIFT_MASK) { - lpe->dist_angle_handle = L2(lpe->B - lpe->A); - } else { - lpe->dist_angle_handle = L2(p - lpe->origin); - } - - // 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 KnotHolderEntityStartingAngle::knot_get() const { @@ -198,13 +171,6 @@ KnotHolderEntityStartingAngle::knot_get() const return lpe->start_pos; } -Geom::Point -KnotHolderEntityRotationAngle::knot_get() const -{ - LPECopyRotate const *lpe = dynamic_cast(_effect); - return lpe->rot_pos; -} - } // namespace CR diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index c84889f57..123c92cdd 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,6 @@ public: /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; - friend class CR::KnotHolderEntityRotationAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -48,6 +47,7 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; + BoolParam copiesTo360; PointParam origin; -- cgit v1.2.3 From 04abdf45fdd7a96b13c09a2a7aabbca95ba9ebb9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 2 Dec 2014 19:36:49 +0100 Subject: adding fussion improvements (bzr r13708.1.3) --- src/live_effects/lpe-copy_rotate.cpp | 122 +++++++++++++++++++++++++++++++++-- src/live_effects/lpe-copy_rotate.h | 1 + 2 files changed, 116 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 51787e292..e0855d452 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -47,6 +47,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), + fusionPaths(_("Fusioned paths"), _("Fusion paths"), "fusionPaths", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) { @@ -55,6 +56,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&copiesTo360) ); + registerParameter( dynamic_cast(&fusionPaths) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -106,14 +108,120 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + if(fusionPaths){ + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(-starting_angle)); + Rotate rot2(-deg_to_rad(rotation_angle_end-starting_angle)); + //Affine t = pre * rot * Translate(origin); + Geom::Path mlineExpanded; + Geom::Point lineStart(0,0); + Geom::Point lineStart[Geom::X] = cos(rot) * 100000.0; + Geom::Point lineStart[Geom::Y] = sin(rot) * 100000.0; + Geom::Point lineEnd(0,0); + Geom::Point lineEnd[Geom::X] = cos(rot2) * 100000.0; + Geom::Point lineEnd[Geom::Y] = sin(rot2) * 100000.0; + mlineExpanded.start( lineStart); + mlineExpanded.appendNew( origin); + mlineExpanded.appendNew( lineEnd); + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + std::vector 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( 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); + Geom::line middleLine; + middleLine->setPoints(origin,middle); + if(middleLine.angle > rot && middleLine < rot2){ + Geom::Path kaleidoscope; + for (int j = 0; j < num_copies; ++j) { + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * j)); + Affine t = pre * rot * Translate(origin); + kaleidoscope = portion.reverse() * t); + kaleidoscope.setInitial(portion.finalPoint()); + portion.append(kaleidoscope); + } + if(i!=0){ + portion.setFinal(portion.initialPoint()); + portion.close(); + } + temp_path.push_back(portion); + } + portion.clear(); + timeStart = timeEnd; + } + Geom::line middleLine; + middleLine->setPoints(origin,original.finalPoint()); + if(cs.size()!=0 && middleLine.angle > rot && middleLine < rot2){ + Geom::Path portion = original.portion(timeStart, original.size()); + portion = portion.reverse(); + + Geom::Path kaleidoscope; + for (int i = 0; i < num_copies; ++i) { + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + kaleidoscope = portion.reverse() * t); + kaleidoscope.setInitial(portion.finalPoint()); + portion.append(kaleidoscope); + } + 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(); + } + output = path_out.toPwSb(); + } else { + for (int i = 0; i < num_copies; ++i) { + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); + } + } } - return output; } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 123c92cdd..735de2300 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,6 +48,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; + BoolParam fusionPaths; PointParam origin; -- cgit v1.2.3 From 9a944b9317cbe94fb7c3c9f976da9ceffedeadf7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 5 Dec 2014 21:20:55 +0100 Subject: adding fussion improvements (bzr r13708.1.5) --- src/live_effects/lpe-copy_rotate.cpp | 153 ++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 553f273fe..7e3e65f23 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,11 +17,14 @@ #include "live_effects/lpe-copy_rotate.h" #include "sp-shape.h" #include "display/curve.h" - +#include <2geom/path.h> +#include <2geom/path-intersection.h> +#include <2geom/sbasis-to-bezier.h> #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> #include <2geom/angle.h> +#include #include "knot-holder-entity.h" #include "knotholder.h" @@ -110,60 +113,57 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusionPaths){ - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(-starting_angle)); - Rotate rot2(-deg_to_rad(rotation_angle_end-starting_angle)); - //Affine t = pre * rot * Translate(origin); - Geom::Path mlineExpanded; - Geom::Point lineStart(0,0); - Geom::Point lineStart[Geom::X] = cos(rot) * 100000.0; - Geom::Point lineStart[Geom::Y] = sin(rot) * 100000.0; - Geom::Point lineEnd(0,0); - Geom::Point lineEnd[Geom::X] = cos(rot2) * 100000.0; - Geom::Point lineEnd[Geom::Y] = sin(rot2) * 100000.0; - mlineExpanded.start( lineStart); - mlineExpanded.appendNew( origin); - mlineExpanded.appendNew( lineEnd); - PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); - for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - std::vector 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( original.initialPoint() ); - original.close(true); + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + std::vector path_out; + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + bool end_open = false; + std::vector temp_path; + double timeStart = 0.0; + int position = 0; + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { + end_open = true; } - Geom::Crossings cs = crossings(original, mlineExpanded); + } + Geom::Path original = (Geom::Path)(*path_it); + if(end_open && path_it2->closed()){ + original.close(false); + original.appendNew( original.initialPoint() ); + original.close(true); + } + //for (int i = 0; i < num_copies; ++i) { + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); + Affine t = pre * rot * Translate(origin); + Geom::Point lineEnd(0,0); + lineEnd[Geom::X] = cos((rotAngle * i) - rotAngle/2.0) * 100000.0; + lineEnd[Geom::Y] = sin((rotAngle * i) - rotAngle/2.0) * 100000.0; + Geom::Path kline; + kline.start((Geom::Point)origin); + kline.appendNew(lineEnd); + Geom::Crossings cs = crossings(original, kline); 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); - Geom::line middleLine; - middleLine->setPoints(origin,middle); - if(middleLine.angle > rot && middleLine < rot2){ - Geom::Path kaleidoscope; - for (int j = 0; j < num_copies; ++j) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * j)); + position = pointSideOfLine((Geom::Point)origin, lineEnd, middle); + if(reverseFusion){ + position *= -1; + } + if(position == 1){ + for (int i = 0; i < num_copies; ++i) { + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); Affine t = pre * rot * Translate(origin); - kaleidoscope = portion.reverse() * t); - kaleidoscope.setInitial(portion.finalPoint()); - portion.append(kaleidoscope); + Geom::Path kaleidoscope = portion * t; + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); } if(i!=0){ portion.setFinal(portion.initialPoint()); @@ -174,23 +174,20 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p portion.clear(); timeStart = timeEnd; } - Geom::line middleLine; - middleLine->setPoints(origin,original.finalPoint()); - if(cs.size()!=0 && middleLine.angle > rot && middleLine < rot2){ - Geom::Path portion = original.portion(timeStart, original.size()); - portion = portion.reverse(); - - Geom::Path kaleidoscope; + position = pointSideOfLine((Geom::Point)origin, lineEnd, original.finalPoint()); + if(reverseFusion){ + position *= -1; + } + if(cs.size()!=0 && position == 1){ for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); + double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); + Rotate rot(rotAngle * i); Affine t = pre * rot * Translate(origin); - kaleidoscope = portion.reverse() * t); + Geom::Path portion = original.portion(timeStart, original.size()); + Geom::Path kaleidoscope = portion * t; kaleidoscope.setInitial(portion.finalPoint()); portion.append(kaleidoscope); } - portion = portion.reverse(); if (!original.closed()){ temp_path.push_back(portion); } else { @@ -205,22 +202,28 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } 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(); } - output = path_out.toPwSb(); - } else { - for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + if(cs.size() == 0 && position == 1){ + for (int i = 0; i < num_copies; ++i) { + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + temp_path.push_back((Geom::Path)(*path_it) * t); + } } + path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); + temp_path.clear(); + if(path_out.size() > 0){ + output.concat(paths_to_pw(path_out)); + } + } else { + for (int i = 0; i < num_copies; ++i) { + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); } } return output; -- cgit v1.2.3 From 1d1ec291d89846be2dbd5ce1466b58baeb743994 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 17 Jan 2015 18:14:04 +0100 Subject: adding Kaleidoscope (bzr r13708.1.8) --- src/live_effects/lpe-copy_rotate.cpp | 164 +++++++++++++++-------------------- src/live_effects/lpe-copy_rotate.h | 6 +- 2 files changed, 73 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 7e3e65f23..1eb1f22f2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -50,7 +50,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), - fusionPaths(_("Fusioned paths"), _("Fusion paths"), "fusionPaths", &wr, this, true), + kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, true), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), dist_angle_handle(100) @@ -60,7 +60,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&copiesTo360) ); - registerParameter( dynamic_cast(&fusionPaths) ); + registerParameter( dynamic_cast(&kaleidoscope) ); registerParameter( dynamic_cast(&starting_angle) ); registerParameter( dynamic_cast(&rotation_angle) ); registerParameter( dynamic_cast(&num_copies) ); @@ -91,6 +91,58 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) dist_angle_handle = L2(B - A); } +void +LPECopyRotate::split(std::vector &path_in,Geom:Path divider,bool start){ + double timeStart = 0.0; + for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + Geom::Path original = path_it; + std::vector temp_path; + Geom::Crossings cs = crossings(original, divider); + 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(divider.initialPoint(), divider.finalPoint(), middle); + if(position == 1 || (!start && position== -1)){ + temp_path.push_back(portion); + } + portion.clear(); + timeStart = timeEnd; + } + position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + if(cs.size()!=0 && (position == 1 || (!start && position== -1))){ + Geom::Path portion = original.portion(timeStart, original.size()); + temp_path.push_back(portion); + portion.clear(); + } + } + path_in = temp_path; +} + +void +LPECopyRotate::setKaleidoscope(std::vector &path_in){ + Geom::Point lineStart(0,0); + lineStart[Geom::X] = cos(starting_angle) * 100000.0; + lineStart[Geom::Y] = sin(starting_angle) * 100000.0; + Geom::Point lineEnd(0,0); + lineEnd[Geom::X] = cos(starting_angle + rotAngle) * 100000.0; + lineEnd[Geom::Y] = sin(starting_angle + rotAngle) * 100000.0; + Geom::Path klineA; + klineA.start(origin); + klineA.appendNew(lineStart); + path_in = split(path_in,klineA,true); + Geom::Path klineB; + klineB.start(origin); + klineB.appendNew(lineEnd); + path_in = split(path_in,klineB,false); + for (int i = 0; i < num_copies; ++i) { + + } +} + Geom::Piecewise > LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -100,7 +152,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; double rotation_angle_end = rotation_angle; - if(copiesTo360){ + if(copiesTo360 || kaleidoscope){ rotation_angle_end = 360.0/(double)num_copies; } rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; @@ -112,19 +164,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(fusionPaths){ - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) + if(kaleidoscope){ std::vector path_out; + std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()){ continue; } - bool end_open = false; - std::vector temp_path; - double timeStart = 0.0; - int position = 0; if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { @@ -137,94 +184,19 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.appendNew( original.initialPoint() ); original.close(true); } - //for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Point lineEnd(0,0); - lineEnd[Geom::X] = cos((rotAngle * i) - rotAngle/2.0) * 100000.0; - lineEnd[Geom::Y] = sin((rotAngle * i) - rotAngle/2.0) * 100000.0; - Geom::Path kline; - kline.start((Geom::Point)origin); - kline.appendNew(lineEnd); - Geom::Crossings cs = crossings(original, kline); - 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((Geom::Point)origin, lineEnd, middle); - if(reverseFusion){ - position *= -1; - } - if(position == 1){ - for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Path kaleidoscope = portion * t; - 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((Geom::Point)origin, lineEnd, original.finalPoint()); - if(reverseFusion){ - position *= -1; - } - if(cs.size()!=0 && position == 1){ - for (int i = 0; i < num_copies; ++i) { - double rotAngle = -deg_to_rad(rotation_angle_end-starting_angle); - Rotate rot(rotAngle * i); - Affine t = pre * rot * Translate(origin); - Geom::Path portion = original.portion(timeStart, original.size()); - Geom::Path kaleidoscope = portion * t; - kaleidoscope.setInitial(portion.finalPoint()); - portion.append(kaleidoscope); - } - 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){ - for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - temp_path.push_back((Geom::Path)(*path_it) * t); - } - } - path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); - temp_path.clear(); - if(path_out.size() > 0){ - output.concat(paths_to_pw(path_out)); - } + tmp_path.push_back(original); + setKaleidoscope(tmp_path); + path_out.push_back(tmp_path); + tmp_path.clear(); + } + output = path_out.toPwSb(); } else { for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); - } + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); } return output; } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 735de2300..d0ad2d6ec 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -36,6 +36,10 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + virtual void kaleidoscope(std::vector &path_in); + + virtual void split(std::vector &path_in,Geom:Path divider,bool start); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -48,7 +52,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; - BoolParam fusionPaths; + BoolParam setKaleidoscope; PointParam origin; -- cgit v1.2.3 From 8deff8fb8acbbfa8c56db9d6e34b93523872a25b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 21 Jan 2015 00:13:00 +0100 Subject: fixing knots (bzr r13708.1.10) --- src/live_effects/lpe-copy_rotate.cpp | 236 ++++++++++++++++++++++++----------- src/live_effects/lpe-copy_rotate.h | 19 ++- 2 files changed, 179 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 1eb1f22f2..20e08a7d8 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -24,7 +24,8 @@ #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> #include <2geom/angle.h> -#include +#include <2geom/line.h> +#include #include "knot-holder-entity.h" #include "knotholder.h" @@ -41,30 +42,35 @@ public: virtual Geom::Point knot_get() const; }; +class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { +public: + KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; } // namespace CR LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), + origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), - kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, true), - - origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), - dist_angle_handle(100) + kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), + dist_angle_handle(100.0) { show_orig_path = true; _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast(&copiesTo360) ); - registerParameter( dynamic_cast(&kaleidoscope) ); - registerParameter( dynamic_cast(&starting_angle) ); - registerParameter( dynamic_cast(&rotation_angle) ); - registerParameter( dynamic_cast(&num_copies) ); - registerParameter( dynamic_cast(&origin) ); + registerParameter(&copiesTo360); + registerParameter(&kaleidoscope); + registerParameter(&starting_angle); + registerParameter(&rotation_angle); + registerParameter(&num_copies); + registerParameter(&origin); num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); @@ -79,65 +85,117 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); - Point A(boundingbox_X.min(), boundingbox_Y.middle()); - Point B(boundingbox_X.max(), boundingbox_Y.middle()); - Point C(boundingbox_X.middle(), boundingbox_Y.middle()); - origin.param_setValue(A); + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); + origin.param_set_value(A); + dist_angle_handle = L2(B - A); + dir = unit_vector(B - A); +} + +void +LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) +{ + using namespace Geom; + original_bbox(lpeitem); + if( kaleidoscope || copiesTo360 ){ + rotation_angle.param_set_value(360.0/(double)num_copies); + } + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); dir = unit_vector(B - A); - dist_angle_handle = L2(B - A); + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; + rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + if( kaleidoscope || copiesTo360 ){ + rot_pos = origin; + } + SPLPEItem * item = const_cast(lpeitem); + item->apply_to_clippath(item); + item->apply_to_mask(item); +} + +bool +LPECopyRotate::side(Geom::Point p1, Geom::Point p2, Geom::Point p) +{ + using Geom::X; + using Geom::Y; + return (p2[Y] - p1[Y])*(p[X] - p1[X]) + (-p2[X] + p1[X])*(p[Y] - p1[Y]) >= 0; +} + +bool +LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) +{ + using Geom::X; + using Geom::Y; + double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); + double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; + double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; + double s = t1 + t2; + + return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; } void -LPECopyRotate::split(std::vector &path_in,Geom:Path divider,bool start){ +LPECopyRotate::split(std::vector &path_in,Geom::Path divider){ double timeStart = 0.0; + std::vector temp_path; for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { if (path_it->empty()){ continue; } - Geom::Path original = path_it; - std::vector temp_path; + Geom::Path original = *path_it; + int position = 0; Geom::Crossings cs = crossings(original, divider); 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(divider.initialPoint(), divider.finalPoint(), middle); - if(position == 1 || (!start && position== -1)){ + Geom::Point sideChecker = portion.pointAt(portion.size()-0.001); + position = side(divider.initialPoint(), divider.finalPoint(), sideChecker); + if(num_copies > 2){ + position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + } + std::cout << position << "\n"; + if(position == true){ temp_path.push_back(portion); } portion.clear(); timeStart = timeEnd; } - position = pointSideOfLine(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); - if(cs.size()!=0 && (position == 1 || (!start && position== -1))){ + position = side(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + if(num_copies > 2){ + position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + } + if(cs.size()!=0 && position == true){ Geom::Path portion = original.portion(timeStart, original.size()); - temp_path.push_back(portion); + if (!original.closed()){ + temp_path.push_back(portion); + } else { + if(cs.size() > 1 && temp_path[0].size() > 0 ){ + portion.setFinal(temp_path[0].initialPoint()); + portion.append(temp_path[0]); + temp_path[0]=portion; + } else { + temp_path.push_back(portion); + } + //temp_path[0].close(); + } portion.clear(); } + if(cs.size()==0){ + temp_path.push_back(original); + } } path_in = temp_path; } void LPECopyRotate::setKaleidoscope(std::vector &path_in){ - Geom::Point lineStart(0,0); - lineStart[Geom::X] = cos(starting_angle) * 100000.0; - lineStart[Geom::Y] = sin(starting_angle) * 100000.0; - Geom::Point lineEnd(0,0); - lineEnd[Geom::X] = cos(starting_angle + rotAngle) * 100000.0; - lineEnd[Geom::Y] = sin(starting_angle + rotAngle) * 100000.0; - Geom::Path klineA; - klineA.start(origin); - klineA.appendNew(lineStart); - path_in = split(path_in,klineA,true); - Geom::Path klineB; - klineB.start(origin); - klineB.appendNew(lineEnd); - path_in = split(path_in,klineB,false); + + split(path_in,hp); for (int i = 0; i < num_copies; ++i) { } @@ -148,30 +206,21 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - double rotation_angle_end = rotation_angle; - if(copiesTo360 || kaleidoscope){ - rotation_angle_end = 360.0/(double)num_copies; + if(num_copies == 1){ + return pwd2_in; } - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; - - A = pwd2_in.firstValue(); - B = pwd2_in.lastValue(); - dir = unit_vector(B - A); Piecewise > output; - Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope){ std::vector path_out; std::vector tmp_path; - PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in * t, 0.1), 0.001); + PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()){ continue; } + bool end_open = false; if (path_it->closed()) { const Geom::Curve &closingline = path_it->back_closed(); if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { @@ -179,24 +228,25 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it2->closed()){ + if(end_open && path_it->closed()){ original.close(false); original.appendNew( original.initialPoint() ); original.close(true); } tmp_path.push_back(original); setKaleidoscope(tmp_path); - path_out.push_back(tmp_path); + path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - output = path_out.toPwSb(); + if(path_out.size()>0){ + output = paths_to_pw(path_out); + } } else { for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); - Affine t = pre * rot * Translate(origin); - output.concat(pwd2_in * t); + Rotate rot(-deg_to_rad(rotation_angle * i)); + Affine t = pre * rot * Translate(origin); + output.concat(pwd2_in * t); + } } return output; } @@ -205,21 +255,40 @@ void LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) { using namespace Geom; - - Path path(start_pos); - path.appendNew((Geom::Point) origin); - path.appendNew(rot_pos); - PathVector pathv; - pathv.push_back(path); + hp_vec.clear(); + 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 sizeDivider = Geom::distance(origin,bbox) + diagonal + 20; + Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; + Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + hp.start(lineStart); + hp.appendNew((Geom::Point)origin); + hp.appendNew(lineEnd); + Geom::PathVector pathv; + pathv.push_back(hp); hp_vec.push_back(pathv); } +void +LPECopyRotate::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); + hp.clear(); +} -void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { +void +LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the starting angle") ); + _("Adjust the starting angle")); + knotholder->add(e); + } + { + KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the rotation angle")); knotholder->add(e); } }; @@ -248,6 +317,26 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } +void +KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + LPECopyRotate* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + lpe->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + if (state & GDK_SHIFT_MASK) { + lpe->dist_angle_handle = L2(lpe->B - lpe->A); + } else { + lpe->dist_angle_handle = L2(p - lpe->origin); + } + + // 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 KnotHolderEntityStartingAngle::knot_get() const { @@ -255,9 +344,14 @@ KnotHolderEntityStartingAngle::knot_get() const return lpe->start_pos; } -} // namespace CR - +Geom::Point +KnotHolderEntityRotationAngle::knot_get() const +{ + LPECopyRotate const *lpe = dynamic_cast(_effect); + return lpe->rot_pos; +} +} // namespace CR /* ######################## */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index d0ad2d6ec..209118925 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -36,29 +36,38 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); - virtual void kaleidoscope(std::vector &path_in); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void split(std::vector &path_in,Geom:Path divider,bool start); + virtual void setKaleidoscope(std::vector &path_in); + + virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); + + virtual bool side(Geom::Point p1, Geom::Point p2, Geom::Point p); + + virtual void split(std::vector &path_in,Geom::Path divider); + + virtual void resetDefaults(SPItem const* item); /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; + friend class CR::KnotHolderEntityRotationAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); private: + PointParam origin; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; - BoolParam setKaleidoscope; - - PointParam origin; + BoolParam kaleidoscope; Geom::Point A; Geom::Point B; Geom::Point dir; + Geom::Path hp; Geom::Point start_pos; Geom::Point rot_pos; -- cgit v1.2.3 From 41368054b3da78b13a049d0020d0eeb4d8a6798d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 10:58:06 +0100 Subject: Added the remove for outer staff to kaleidoscope (bzr r13708.1.12) --- src/live_effects/lpe-copy_rotate.cpp | 131 ++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 5 +- 2 files changed, 71 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 20e08a7d8..1c01e2aaf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -89,7 +89,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); - origin.param_set_value(A); + origin.param_setValue(A); dist_angle_handle = L2(B - A); dir = unit_vector(B - A); } @@ -102,7 +102,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) original_bbox(lpeitem); if( kaleidoscope || copiesTo360 ){ rotation_angle.param_set_value(360.0/(double)num_copies); - } + } + if(dist_angle_handle < 1.0){ + dist_angle_handle = 1.0; + } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); dir = unit_vector(B - A); @@ -118,17 +121,18 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -bool -LPECopyRotate::side(Geom::Point p1, Geom::Point p2, Geom::Point p) +int +LPECopyRotate::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X) { - using Geom::X; - using Geom::Y; - return (p2[Y] - p1[Y])*(p[X] - p1[X]) + (-p2[X] + p1[X])*(p[Y] - p1[Y]) >= 0; + //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); } bool LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) { + //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html using Geom::X; using Geom::Y; double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); @@ -140,62 +144,60 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_in,Geom::Path divider){ +LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ + std::vector tmp_path; double timeStart = 0.0; - std::vector temp_path; - for (Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - Geom::Path original = *path_it; - int position = 0; - Geom::Crossings cs = crossings(original, divider); - for(unsigned int i = 0; i < cs.size(); i++) { - double timeEnd = cs[i].ta; - Geom::Path portion = original.portion(timeStart, timeEnd); - Geom::Point sideChecker = portion.pointAt(portion.size()-0.001); - position = side(divider.initialPoint(), divider.finalPoint(), sideChecker); - if(num_copies > 2){ - position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); - } - std::cout << position << "\n"; - if(position == true){ - temp_path.push_back(portion); - } - portion.clear(); - timeStart = timeEnd; - } - position = side(divider.initialPoint(), divider.finalPoint(), original.finalPoint()); + Geom::Path original = path_on[0]; + int position = 0; + Geom::Crossings cs = crossings(original,divider); + std::vector 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 timeEnd = crossed[i]; + Geom::Path portionOriginal = original.portion(timeStart,timeEnd); + Geom::Point sideChecker = portionOriginal.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); if(num_copies > 2){ - position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider.finalPoint()); + position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size()!=0 && position == true){ - Geom::Path portion = original.portion(timeStart, original.size()); - if (!original.closed()){ - temp_path.push_back(portion); + if(position == 1){ + tmp_path.push_back(portionOriginal); + } + portionOriginal.clear(); + timeStart = timeEnd; + } + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); + if(num_copies > 2){ + position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + } + if(cs.size() > 0 && position == 1){ + Geom::Path portionOriginal = original.portion(timeStart, original.size()); + if (!original.closed()){ + tmp_path.push_back(portionOriginal); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ){ + portionOriginal.setFinal(tmp_path[0].initialPoint()); + portionOriginal.append(tmp_path[0]); + tmp_path[0] = portionOriginal; } else { - if(cs.size() > 1 && temp_path[0].size() > 0 ){ - portion.setFinal(temp_path[0].initialPoint()); - portion.append(temp_path[0]); - temp_path[0]=portion; - } else { - temp_path.push_back(portion); - } - //temp_path[0].close(); + tmp_path.push_back(portionOriginal); } - portion.clear(); - } - if(cs.size()==0){ - temp_path.push_back(original); + //temp_path[0].close(); } + portionOriginal.clear(); + } + if(cs.size()==0 && position == 1){ + tmp_path.push_back(original); } - path_in = temp_path; + path_on = tmp_path; } void -LPECopyRotate::setKaleidoscope(std::vector &path_in){ - - split(path_in,hp); +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ + split(path_on,divider); for (int i = 0; i < num_copies; ++i) { } @@ -210,6 +212,16 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p return pwd2_in; } + 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 sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; + Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + //Note:: beter way to do this + //Whith AppendNew have problems whith the crossing order + Geom::Path divider = Geom::Path(lineStart); + divider.appendNew((Geom::Point)origin); + divider.appendNew(lineEnd); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope){ @@ -234,7 +246,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path); + setKaleidoscope(tmp_path,divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } @@ -256,14 +268,10 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector((Geom::Point)origin); - hp.appendNew(lineEnd); + hp.appendNew(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); Geom::PathVector pathv; pathv.push_back(hp); hp_vec.push_back(pathv); @@ -274,7 +282,6 @@ LPECopyRotate::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); original_bbox(SP_LPE_ITEM(item)); - hp.clear(); } void diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 209118925..78e3b1950 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,11 +38,11 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); - virtual bool side(Geom::Point p1, Geom::Point p2, Geom::Point p); + virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); virtual void split(std::vector &path_in,Geom::Path divider); @@ -67,7 +67,6 @@ private: Geom::Point A; Geom::Point B; Geom::Point dir; - Geom::Path hp; Geom::Point start_pos; Geom::Point rot_pos; -- cgit v1.2.3 From d1a09f4fd642b79542401c6e4eb83e79369c0f9b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 11:08:58 +0100 Subject: added missing header from a merge (bzr r13708.1.14) --- src/live_effects/lpe-copy_rotate.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 35b5c1eb2..d1022dbc2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -13,7 +13,8 @@ #include #include - +#include <2geom/path-intersection.h> +#include <2geom/sbasis-to-bezier.h> #include "live_effects/lpe-copy_rotate.h" #include <2geom/path.h> #include <2geom/transforms.h> @@ -191,8 +192,13 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ void LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ split(path_on,divider); - for (int i = 0; i < num_copies; ++i) { - + for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + for (int i = 0; i < num_copies; ++i) { + + } } } -- cgit v1.2.3 From 8d82767ca9ff65622eac487afd6aeba78713add5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 12:40:19 +0100 Subject: reverting to non wroken branch (bzr r13708.1.15) --- src/live_effects/lpe-copy_rotate.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index d1022dbc2..3103d8293 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -192,12 +192,17 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ void LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ split(path_on,divider); + Geom::Affine pre = Geom::Translate(-origin) * Geom::Rotate(-Geom::deg_to_rad(starting_angle)); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { if (path_it->empty()){ continue; } for (int i = 0; i < num_copies; ++i) { - + Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * i)); + Geom::Affine t = pre * rot * Geom::Translate(origin); + Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Geom::Path append = *path_it * sca * t; + path_on.push_back(append); } } } -- cgit v1.2.3 From 2218eee67d0032e118cb711b7c612f7b580a6294 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 24 Jan 2015 18:11:22 +0100 Subject: Kaleidoscope check (bzr r13708.1.16) --- src/live_effects/lpe-copy_rotate.cpp | 70 +++++++++++++++++++++++++++++------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 59 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 3103d8293..6c16c6194 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -94,9 +94,18 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if( kaleidoscope || copiesTo360 ){ + if(kaleidoscope || copiesTo360 ){ rotation_angle.param_set_value(360.0/(double)num_copies); } + if(kaleidoscope){ + num_copies.param_set_increments(2,2); + if((int)num_copies%2 !=0){ + num_copies.param_set_value(num_copies+1); + } + } else { + num_copies.param_set_increments(1,1); + } + if(dist_angle_handle < 1.0){ dist_angle_handle = 1.0; } @@ -190,21 +199,58 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider){ +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider){ split(path_on,divider); - Geom::Affine pre = Geom::Translate(-origin) * Geom::Rotate(-Geom::deg_to_rad(starting_angle)); + std::vector tmp_path; + Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - for (int i = 0; i < num_copies; ++i) { - Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * i)); - Geom::Affine t = pre * rot * Geom::Translate(origin); + Geom::Path original = *path_it; + if (path_it->empty()){ + continue; + } + std::vector tmp_path2; + Geom::Path appendPath = original; + for (int i = 0; i < num_copies; ++i) { + Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); + Geom::Affine m = pre * rot * Geom::Translate(origin); + if(i%2 != 0){ + Geom::Point A = (Geom::Point)origin; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; + Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); + double hyp = Geom::distance(A, B); + double c = (B[0] - A[0]) / hyp; // cos(alpha) + double s = (B[1] - A[1]) / hyp; // sin(alpha) + + Geom::Affine m2(c, -s, s, c, 0.0, 0.0); Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - Geom::Path append = *path_it * sca * t; - path_on.push_back(append); + + Geom::Affine tmpM = m1.inverse() * m2; + m = tmpM; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + } else { + appendPath = original; } + appendPath *= m; + if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint())){ + tmp_path2[tmp_path2.size()-1].append(appendPath.reverse()); + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())){ + tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); + tmp_path2[tmp_path2.size()-1].append(appendPath); + tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); + } else { + tmp_path2.push_back(appendPath); + } + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())){ + tmp_path2[tmp_path2.size()-1].close(); + } + } + tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); + tmp_path2.clear(); } + path_on = tmp_path; + tmp_path.clear(); } Geom::Piecewise > @@ -250,7 +296,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider); + setKaleidoscope(tmp_path,divider,sizeDivider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 78e3b1950..bdbc61d07 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From b21958f914e82435e935bb732b64cdf3f685c3f1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Mar 2015 14:57:06 +0100 Subject: adding rotation transform (bzr r13708.1.20) --- src/live_effects/lpe-copy_rotate.cpp | 18 ++++++++++++++++++ src/live_effects/lpe-copy_rotate.h | 2 ++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 63d6b8bfa..5474bfb70 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -89,6 +89,24 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) dir = unit_vector(B - A); } +void +LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) +{ + if(postmul->isRotation()){ + Geom::Point rot = (Geom::Rotate)postmul::vector(); + coord angle = rad_to_deg(atan2(rot)); + starting_angle.param_setValue(starting_angle + angle); + starting_angle.param_update_default(starting_angle + angle); + rotation_angle.param_setValue(rotation_angle + angle); + rotation_angle.param_update_default(rotation_angle + angle); + } + // cycle through all parameters. Most parameters will not need transformation, but path and point params do. + + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { + Parameter * param = *it; + param->param_transform_multiply(postmul, set); + } +} void LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index bdbc61d07..d0a5b004b 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -48,6 +48,8 @@ public: virtual void resetDefaults(SPItem const* item); + virtual void transform_multiply(Geom::Affine const& postmul, bool set); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; friend class CR::KnotHolderEntityRotationAngle; -- cgit v1.2.3 From 2763fbcc2619a390e5f81c2887b1f8f312eb5e65 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Mar 2015 22:04:40 +0100 Subject: Allow rotate copies whithout distorsion in kaleidoscope shapes (bzr r13708.1.22) --- src/live_effects/lpe-copy_rotate.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 5474bfb70..2e87133b3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -92,13 +92,10 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(postmul->isRotation()){ - Geom::Point rot = (Geom::Rotate)postmul::vector(); - coord angle = rad_to_deg(atan2(rot)); - starting_angle.param_setValue(starting_angle + angle); - starting_angle.param_update_default(starting_angle + angle); - rotation_angle.param_setValue(rotation_angle + angle); - rotation_angle.param_update_default(rotation_angle + angle); + if(kaleidoscope){ + Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); + angle += starting_angle; + starting_angle.param_set_value(angle); } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. -- cgit v1.2.3 From 1973e31feb91e5a2bbdd1c3e36b20d1681123447 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:01:46 +0200 Subject: astyle copy-rotate LPE (bzr r13708.1.25) --- src/live_effects/lpe-copy_rotate.cpp | 77 +++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 6 +-- 2 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 2e87133b3..bb331b37a 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -65,7 +65,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : registerParameter(&rotation_angle); registerParameter(&num_copies); registerParameter(&origin); - + num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); } @@ -92,13 +92,13 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(kaleidoscope){ + if(kaleidoscope) { Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); } // cycle through all parameters. Most parameters will not need transformation, but path and point params do. - + for (std::vector::iterator it = param_vector.begin(); it != param_vector.end(); ++it) { Parameter * param = *it; param->param_transform_multiply(postmul, set); @@ -110,19 +110,19 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copiesTo360 ){ + if(kaleidoscope || copiesTo360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope){ + if(kaleidoscope) { num_copies.param_set_increments(2,2); - if((int)num_copies%2 !=0){ + if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); } } else { num_copies.param_set_increments(1,1); } - if(dist_angle_handle < 1.0){ + if(dist_angle_handle < 1.0) { dist_angle_handle = 1.0; } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); @@ -132,7 +132,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copiesTo360 ){ + if( kaleidoscope || copiesTo360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -140,7 +140,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -int +int LPECopyRotate::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 @@ -163,7 +163,8 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ +LPECopyRotate::split(std::vector &path_on,Geom::Path divider) +{ std::vector tmp_path; double timeStart = 0.0; Geom::Path original = path_on[0]; @@ -179,25 +180,25 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ Geom::Path portionOriginal = original.portion(timeStart,timeEnd); Geom::Point sideChecker = portionOriginal.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); - if(num_copies > 2){ + if(num_copies > 2) { position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(position == 1){ + if(position == 1) { tmp_path.push_back(portionOriginal); } portionOriginal.clear(); timeStart = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(num_copies > 2){ + if(num_copies > 2) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size() > 0 && position == 1){ + if(cs.size() > 0 && position == 1) { Geom::Path portionOriginal = original.portion(timeStart, original.size()); - if (!original.closed()){ + if (!original.closed()) { tmp_path.push_back(portionOriginal); } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ){ + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { portionOriginal.setFinal(tmp_path[0].initialPoint()); portionOriginal.append(tmp_path[0]); tmp_path[0] = portionOriginal; @@ -208,20 +209,21 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider){ } portionOriginal.clear(); } - if(cs.size()==0 && position == 1){ + if(cs.size()==0 && position == 1) { tmp_path.push_back(original); } path_on = tmp_path; } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider){ +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider) +{ split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { Geom::Path original = *path_it; - if (path_it->empty()){ + if (path_it->empty()) { continue; } std::vector tmp_path2; @@ -229,7 +231,7 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); - if(i%2 != 0){ + if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); @@ -249,44 +251,44 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi appendPath = original; } appendPath *= m; - if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))){ + if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))) { Geom::Path tmpAppend = appendPath.reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())) { Geom::Path tmpAppend = appendPath.reverse(); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); tmp_path2[tmp_path2.size()-1].append(tmpAppend); tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())) { Geom::Path tmpAppend = appendPath.reverse(); tmpAppend.setInitial(tmp_path2[0].finalPoint()); tmp_path2[0].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())){ + } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())) { Geom::Path tmpAppend = appendPath; tmp_path2[0] = tmp_path2[0].reverse(); tmpAppend.setInitial(tmp_path2[0].finalPoint()); tmp_path2[0].append(tmpAppend); tmp_path2[0] = tmp_path2[0].reverse(); - } else { + } else { tmp_path2.push_back(appendPath); } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())){ + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())) { tmp_path2[tmp_path2.size()-1].close(); } } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())){ + if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())) { tmp_path2[0].close(); } tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); @@ -301,12 +303,12 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1){ + if(num_copies == 1) { return pwd2_in; } 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())); + Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; @@ -317,12 +319,12 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(lineEnd); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(kaleidoscope){ + if(kaleidoscope) { std::vector path_out; std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()){ + if (path_it->empty()) { continue; } bool end_open = false; @@ -333,7 +335,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()){ + if(end_open && path_it->closed()) { original.close(false); original.appendNew( original.initialPoint() ); original.close(true); @@ -343,7 +345,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - if(path_out.size()>0){ + if(path_out.size()>0) { output = paths_to_pw(path_out); } } else { @@ -377,8 +379,9 @@ LPECopyRotate::resetDefaults(SPItem const* item) original_bbox(SP_LPE_ITEM(item)); } -void -LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { +void +LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index d0a5b004b..de00226a4 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -22,9 +22,9 @@ namespace Inkscape { namespace LivePathEffect { namespace CR { - // we need a separate namespace to avoid clashes with LPEPerpBisector - class KnotHolderEntityStartingAngle; - class KnotHolderEntityRotationAngle; +// we need a separate namespace to avoid clashes with LPEPerpBisector +class KnotHolderEntityStartingAngle; +class KnotHolderEntityRotationAngle; } class LPECopyRotate : public Effect, GroupBBoxEffect { -- cgit v1.2.3 From d163d3b01c24671f3124c16455d8654d7a1523f7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Apr 2015 21:13:54 +0200 Subject: Rename some variables to fit coding style (bzr r13708.1.26) --- src/live_effects/lpe-copy_rotate.cpp | 136 +++++++++++++++++------------------ src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 69 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index bb331b37a..4fd605b6d 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -51,7 +51,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), - copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), + copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), dist_angle_handle(100.0) { @@ -59,7 +59,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter(&copiesTo360); + registerParameter(&copies_to_360); registerParameter(&kaleidoscope); registerParameter(&starting_angle); registerParameter(&rotation_angle); @@ -110,7 +110,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copiesTo360 ) { + if(kaleidoscope || copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } if(kaleidoscope) { @@ -132,7 +132,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copiesTo360 ) { + if( kaleidoscope || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -166,7 +166,7 @@ void LPECopyRotate::split(std::vector &path_on,Geom::Path divider) { std::vector tmp_path; - double timeStart = 0.0; + double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; Geom::Crossings cs = crossings(original,divider); @@ -177,37 +177,37 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) std::sort (crossed.begin(), crossed.end()); for(unsigned int i = 0; i < crossed.size(); i++) { double timeEnd = crossed[i]; - Geom::Path portionOriginal = original.portion(timeStart,timeEnd); - Geom::Point sideChecker = portionOriginal.pointAt(0.001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), sideChecker); + Geom::Path portion_original = original.portion(time_start,timeEnd); + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); if(num_copies > 2) { - position = pointInTriangle(sideChecker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } - portionOriginal.clear(); - timeStart = timeEnd; + portion_original.clear(); + time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); if(num_copies > 2) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(cs.size() > 0 && position == 1) { - Geom::Path portionOriginal = original.portion(timeStart, original.size()); + Geom::Path portion_original = original.portion(time_start, original.size()); if (!original.closed()) { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } else { if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portionOriginal.setFinal(tmp_path[0].initialPoint()); - portionOriginal.append(tmp_path[0]); - tmp_path[0] = portionOriginal; + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; } else { - tmp_path.push_back(portionOriginal); + tmp_path.push_back(portion_original); } //temp_path[0].close(); } - portionOriginal.clear(); + portion_original.clear(); } if(cs.size()==0 && position == 1) { tmp_path.push_back(original); @@ -216,7 +216,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double sizeDivider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double size_divider) { split(path_on,divider); std::vector tmp_path; @@ -226,14 +226,14 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi if (path_it->empty()) { continue; } - std::vector tmp_path2; - Geom::Path appendPath = original; + std::vector tmp_path_helper; + Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; - Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * sizeDivider; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) @@ -248,51 +248,51 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi m = m * m2.inverse(); m = m * m1; } else { - appendPath = original; + append_path = original; } - appendPath *= m; - if(i != 0 && tmp_path2.size() > 0 &&( Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.finalPoint()))) { - Geom::Path tmpAppend = appendPath.reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].initialPoint(),appendPath.finalPoint())) { - Geom::Path tmpAppend = appendPath.reverse(); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - tmpAppend.setInitial(tmp_path2[tmp_path2.size()-1].finalPoint()); - tmp_path2[tmp_path2.size()-1].append(tmpAppend); - tmp_path2[tmp_path2.size()-1] = tmp_path2[tmp_path2.size()-1].reverse(); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),appendPath.finalPoint())) { - Geom::Path tmpAppend = appendPath.reverse(); - tmpAppend.setInitial(tmp_path2[0].finalPoint()); - tmp_path2[0].append(tmpAppend); - } else if(i != 0 && tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].initialPoint(),appendPath.initialPoint())) { - Geom::Path tmpAppend = appendPath; - tmp_path2[0] = tmp_path2[0].reverse(); - tmpAppend.setInitial(tmp_path2[0].finalPoint()); - tmp_path2[0].append(tmpAppend); - tmp_path2[0] = tmp_path2[0].reverse(); + append_path *= m; + if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { + Geom::Path tmp_append = append_path.reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reverse(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { - tmp_path2.push_back(appendPath); + tmp_path_helper.push_back(append_path); } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[tmp_path2.size()-1].finalPoint(),tmp_path2[tmp_path2.size()-1].initialPoint())) { - tmp_path2[tmp_path2.size()-1].close(); + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1].close(); } } - if(tmp_path2.size() > 0 && Geom::are_near(tmp_path2[0].finalPoint(),tmp_path2[0].initialPoint())) { - tmp_path2[0].close(); + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { + tmp_path_helper[0].close(); } - tmp_path.insert(tmp_path.end(), tmp_path2.begin(), tmp_path2.end()); - tmp_path2.clear(); + tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); + tmp_path_helper.clear(); } path_on = tmp_path; tmp_path.clear(); @@ -309,14 +309,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p 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 sizeDivider = Geom::distance(origin,bbox) + (diagonal * 2); - Geom::Point lineStart = origin + dir * Rotate(-deg_to_rad(starting_angle)) * sizeDivider; - Geom::Point lineEnd = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * sizeDivider; + double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); + Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order - Geom::Path divider = Geom::Path(lineStart); + Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); - divider.appendNew(lineEnd); + divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -341,7 +341,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider,sizeDivider); + setKaleidoscope(tmp_path,divider,size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index de00226a4..83f4a6984 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -63,7 +63,7 @@ private: ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; - BoolParam copiesTo360; + BoolParam copies_to_360; BoolParam kaleidoscope; Geom::Point A; -- cgit v1.2.3 From 78f080901f40a7390559f88ab14465131bb02717 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Jun 2015 23:46:40 +0200 Subject: opening kaleidscope (bzr r13708.1.28) --- src/live_effects/lpe-copy_rotate.cpp | 95 ++++++++++++++++++++++++++++++++++-- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 94 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 4fd605b6d..c119ca02e 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -110,10 +110,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(kaleidoscope || copies_to_360 ) { + if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope) { + if(kaleidoscope && copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -216,8 +216,72 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, double size_divider) +LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider_extreme) { + std::vector tmp_path; + double time_start = 0.0; + Geom::Path original = path_on[0]; + int position = 0; + Geom::Crossings cs = crossings(original,divider_extreme); + std::vector 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 timeEnd = crossed[i]; + Geom::Path portion_original = original.portion(time_start,timeEnd); + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), side_checker); + if(num_copies > 2) { + position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); + } + if(position == 1) { + Geom::Path start = Geom::Path(divider_extreme.at(0)); + start.appendNew(divider_extreme.at(1)); + if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + portion_original.reverse(); + } + tmp_path.push_back(portion_original); + } + portion_original.clear(); + time_start = timeEnd; + } + position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), original.finalPoint()); + if(num_copies > 2) { + position = pointInTriangle(original.finalPoint(), divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); + } + if(cs.size() > 0 && position == 1) { + Geom::Path portion_original = original.portion(time_start, original.size()); + Geom::Path start = Geom::Path(divider_extreme.at(0)); + start.appendNew(divider_extreme.at(1)); + if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + portion_original.reverse(); + } + if (!original.closed()) { + tmp_path.push_back(portion_original); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; + } else { + tmp_path.push_back(portion_original); + } + //temp_path[0].close(); + } + portion_original.clear(); + } + if(cs.size()==0 && position == 1) { + tmp_path.push_back(original); + } + path_on = tmp_path; +} + +void +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_extreme, double size_divider) +{ + std::vector path_on_start = path_on; split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); @@ -282,6 +346,21 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0].append(tmp_append); tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { + if(rotation_angle * num_copies != 360){ + split_start(path_on_start,divider_extreme); + for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { + Geom::Path original_start = *path_it_start; + if (path_it->empty()) { + continue; + } + std::vector tmp_path_helper; + if(tmp_path_helper.size() > 0 && Geom::are_near(append_path.initialPoint(),path_it_start[0].initialPoint())) { + path_it_start.reverse(); + path_it_start.append(append_path); + append_path = path_it_start; + } + } + } tmp_path_helper.push_back(append_path); } if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { @@ -317,6 +396,14 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); + Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle/2)+starting_angle)) * size_divider; + Geom::Path divider_start = Geom::Path(line_start); + divider_start.appendNew((Geom::Point)origin); + divider_start.appendNew(line_oposite); + Geom::Path divider_end = Geom::Path(line_end); + divider_end.appendNew((Geom::Point)origin); + divider_end.appendNew(line_oposite); + Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -341,7 +428,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider,size_divider); + setKaleidoscope(tmp_path,divider, divider_extreme, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 83f4a6984..638f8a413 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path extreme, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -46,6 +46,8 @@ public: virtual void split(std::vector &path_in,Geom::Path divider); + virtual void split_extreme(std::vector &path_on,Geom::Path divider_extreme); + virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); -- cgit v1.2.3 From 53ff3799d1f7c05cfa7f1384eb39b5105c29f9ab Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 2 Jun 2015 19:29:54 +0200 Subject: opening kaleidscope (bzr r13708.1.30) --- src/live_effects/lpe-copy_rotate.cpp | 27 +++++++++++++-------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index c119ca02e..f9d1bffee 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -237,9 +237,9 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); } if(position == 1) { - Geom::Path start = Geom::Path(divider_extreme.at(0)); - start.appendNew(divider_extreme.at(1)); - if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); + start.appendNew(divider_extreme.pointAt(1)); + if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ portion_original.reverse(); } tmp_path.push_back(portion_original); @@ -253,9 +253,9 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - Geom::Path start = Geom::Path(divider_extreme.at(0)); - start.appendNew(divider_extreme.at(1)); - if(!are_near(nearest_point(portion_original.initialPoint(),start),portion_original.initialPoint())){ + Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); + start.appendNew(divider_extreme.pointAt(1)); + if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ portion_original.reverse(); } if (!original.closed()) { @@ -279,7 +279,7 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_extreme, double size_divider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -347,18 +347,17 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { if(rotation_angle * num_copies != 360){ - split_start(path_on_start,divider_extreme); + split_extreme(path_on_start,divider_start); for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { Geom::Path original_start = *path_it_start; if (path_it->empty()) { continue; } - std::vector tmp_path_helper; - if(tmp_path_helper.size() > 0 && Geom::are_near(append_path.initialPoint(),path_it_start[0].initialPoint())) { - path_it_start.reverse(); - path_it_start.append(append_path); - append_path = path_it_start; + if(Geom::are_near(append_path.initialPoint(),original_start.initialPoint())) { + original_start.reverse(); } + original_start.append(append_path); + append_path = original_start; } } tmp_path_helper.push_back(append_path); @@ -428,7 +427,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_extreme, size_divider); + setKaleidoscope(tmp_path,divider, divider_start, divider_end, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 638f8a413..e16d3ceee 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path extreme, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From 22ca2d7d903022da13a50ac2517e1ff2e3b5257d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 00:54:55 +0200 Subject: opening kaleidscope (bzr r13708.1.32) --- src/live_effects/lpe-copy_rotate.cpp | 134 +++++++++++++---------------------- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 51 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index f9d1bffee..990bc1192 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -113,7 +113,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope && copies_to_360) { + if(kaleidoscope && rotation_angle * num_copies > 360 && rotation_angle > 0){ + num_copies.param_set_value(floor(360/rotation_angle)); + } + if(kaleidoscope || copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -169,6 +172,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; + Geom::Line divider_line(divider.pointAt(0),divider.pointAt(1)); Geom::Crossings cs = crossings(original,divider); std::vector crossed; for(unsigned int i = 0; i < cs.size(); i++) { @@ -184,6 +188,9 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { + if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ + portion_original = portion_original.reverse(); + } tmp_path.push_back(portion_original); } portion_original.clear(); @@ -195,68 +202,8 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if (!original.closed()) { - tmp_path.push_back(portion_original); - } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion_original.setFinal(tmp_path[0].initialPoint()); - portion_original.append(tmp_path[0]); - tmp_path[0] = portion_original; - } else { - tmp_path.push_back(portion_original); - } - //temp_path[0].close(); - } - portion_original.clear(); - } - if(cs.size()==0 && position == 1) { - tmp_path.push_back(original); - } - path_on = tmp_path; -} - -void -LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider_extreme) -{ - std::vector tmp_path; - double time_start = 0.0; - Geom::Path original = path_on[0]; - int position = 0; - Geom::Crossings cs = crossings(original,divider_extreme); - std::vector 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 timeEnd = crossed[i]; - Geom::Path portion_original = original.portion(time_start,timeEnd); - Geom::Point side_checker = portion_original.pointAt(0.001); - position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), side_checker); - if(num_copies > 2) { - position = pointInTriangle(side_checker, divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); - } - if(position == 1) { - Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); - start.appendNew(divider_extreme.pointAt(1)); - if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ - portion_original.reverse(); - } - tmp_path.push_back(portion_original); - } - portion_original.clear(); - time_start = timeEnd; - } - position = pointSideOfLine(divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint(), original.finalPoint()); - if(num_copies > 2) { - position = pointInTriangle(original.finalPoint(), divider_extreme.initialPoint(), divider_extreme[0].finalPoint(), divider_extreme[1].finalPoint()); - } - if(cs.size() > 0 && position == 1) { - Geom::Path portion_original = original.portion(time_start, original.size()); - Geom::Path start = Geom::Path(divider_extreme.pointAt(0)); - start.appendNew(divider_extreme.pointAt(1)); - if(!are_near(start.pointAt(nearest_point(portion_original.initialPoint(),start)),portion_original.initialPoint())){ - portion_original.reverse(); + if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ + portion_original = portion_original.reverse(); } if (!original.closed()) { tmp_path.push_back(portion_original); @@ -279,7 +226,7 @@ LPECopyRotate::split_extreme(std::vector &path_on,Geom::Path divider } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double size_divider) +LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -346,26 +293,49 @@ LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divi tmp_path_helper[0].append(tmp_append); tmp_path_helper[0] = tmp_path_helper[0].reverse(); } else { - if(rotation_angle * num_copies != 360){ - split_extreme(path_on_start,divider_start); - for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { - Geom::Path original_start = *path_it_start; - if (path_it->empty()) { - continue; - } - if(Geom::are_near(append_path.initialPoint(),original_start.initialPoint())) { - original_start.reverse(); - } - original_start.append(append_path); - append_path = original_start; - } - } tmp_path_helper.push_back(append_path); } if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { tmp_path_helper[tmp_path_helper.size()-1].close(); } } + if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ + split(path_on_start,divider_start); + for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { + Geom::Path original_start = *path_it_start; + if (path_it->empty()) { + continue; + } + + if( Geom::are_near(tmp_path_helper[0].initialPoint(),original_start.initialPoint())){ + Geom::Point A(divider_start.pointAt(1)); + Geom::Point B(divider_start.pointAt(2)); + + Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); + double hyp = Geom::distance(A, B); + double c = (B[0] - A[0]) / hyp; // cos(alpha) + double s = (B[1] - A[1]) / hyp; // sin(alpha) + + Geom::Affine m2(c, -s, s, c, 0.0, 0.0); + Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + + Geom::Affine m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + original_start.setInitial(tmp_path_helper[0].initialPoint()); + Geom::Path mirror = original_start * m; + mirror = mirror.reverse(); + mirror.setInitial(original_start.finalPoint()); + original_start.append(mirror); + original_start = original_start.reverse(); + original_start.setFinal(tmp_path_helper[0].initialPoint()); + original_start.append(tmp_path_helper[0]); + tmp_path_helper[0] = original_start; + } + } + } + if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { tmp_path_helper[0].close(); } @@ -395,14 +365,10 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); - Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle/2)+starting_angle)) * size_divider; + Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle * num_copies /2)+starting_angle + 180)) * size_divider; Geom::Path divider_start = Geom::Path(line_start); divider_start.appendNew((Geom::Point)origin); divider_start.appendNew(line_oposite); - Geom::Path divider_end = Geom::Path(line_end); - divider_end.appendNew((Geom::Point)origin); - divider_end.appendNew(line_oposite); - Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(kaleidoscope) { @@ -427,7 +393,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_start, divider_end, size_divider); + setKaleidoscope(tmp_path,divider, divider_start, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index e16d3ceee..efbb5f746 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, Geom::Path divider_end, double sizeDivider); + virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -46,8 +46,6 @@ public: virtual void split(std::vector &path_in,Geom::Path divider); - virtual void split_extreme(std::vector &path_on,Geom::Path divider_extreme); - virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); -- cgit v1.2.3 From d50fe92ba2df09544c11aca985e1746ecdc47fe2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 01:20:27 +0200 Subject: opening kaleidscope (bzr r13708.1.33) --- src/live_effects/lpe-copy_rotate.cpp | 24 ++++++++++++------------ src/live_effects/lpe-copy_rotate.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 990bc1192..559e117cf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -52,7 +52,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - kaleidoscope(_("kaleidoscope"), _("kaleidoscope"), "kaleidoscope", &wr, this, false), + fusion_paths(_("Fusioned paths"), _("Fusion paths by helper line"), "fusion_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -60,7 +60,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copies_to_360); - registerParameter(&kaleidoscope); + registerParameter(&fusion_paths); registerParameter(&starting_angle); registerParameter(&rotation_angle); registerParameter(&num_copies); @@ -92,7 +92,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(kaleidoscope) { + if(fusion_paths) { Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); @@ -113,10 +113,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(kaleidoscope && rotation_angle * num_copies > 360 && rotation_angle > 0){ + if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ num_copies.param_set_value(floor(360/rotation_angle)); } - if(kaleidoscope || copies_to_360) { + if(fusion_paths || copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -135,7 +135,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; - if( kaleidoscope || copies_to_360 ) { + if( fusion_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -189,7 +189,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(position == 1) { if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - portion_original = portion_original.reverse(); + //portion_original = portion_original.reverse(); } tmp_path.push_back(portion_original); } @@ -203,7 +203,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - portion_original = portion_original.reverse(); + // portion_original = portion_original.reverse(); } if (!original.closed()) { tmp_path.push_back(portion_original); @@ -226,7 +226,7 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setKaleidoscope(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) +LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) { std::vector path_on_start = path_on; split(path_on,divider); @@ -359,7 +359,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; - Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle + starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order Geom::Path divider = Geom::Path(line_start); @@ -371,7 +371,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider_start.appendNew(line_oposite); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); - if(kaleidoscope) { + if(fusion_paths) { std::vector path_out; std::vector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); @@ -393,7 +393,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setKaleidoscope(tmp_path,divider, divider_start, size_divider); + setFusion(tmp_path,divider, divider_start, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index efbb5f746..02141b359 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setKaleidoscope(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); + virtual void setFusion(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); @@ -64,7 +64,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam kaleidoscope; + BoolParam fusion_paths; Geom::Point A; Geom::Point B; -- cgit v1.2.3 From ee3b91ebda768eb483c159dc3072cb5a20df5086 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 20:37:00 +0200 Subject: Change from kaleidoscope to multiangle fusion (bzr r13708.1.34) --- src/live_effects/lpe-copy_rotate.cpp | 77 +++++++++++++----------------------- src/live_effects/lpe-copy_rotate.h | 2 +- 2 files changed, 28 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 559e117cf..d12c03f7e 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -116,7 +116,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ num_copies.param_set_value(floor(360/rotation_angle)); } - if(fusion_paths || copies_to_360) { + if(fusion_paths && copies_to_360) { num_copies.param_set_increments(2,2); if((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -172,7 +172,6 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; - Geom::Line divider_line(divider.pointAt(0),divider.pointAt(1)); Geom::Crossings cs = crossings(original,divider); std::vector crossed; for(unsigned int i = 0; i < cs.size(); i++) { @@ -184,27 +183,21 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) Geom::Path portion_original = original.portion(time_start,timeEnd); Geom::Point side_checker = portion_original.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(num_copies > 2) { + if(rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(position == 1) { - if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - //portion_original = portion_original.reverse(); - } tmp_path.push_back(portion_original); } portion_original.clear(); time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(num_copies > 2) { + if(rotation_angle != 180) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if(!Geom::are_near(portion_original.pointAt(0),divider_line)){ - // portion_original = portion_original.reverse(); - } if (!original.closed()) { tmp_path.push_back(portion_original); } else { @@ -215,7 +208,6 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } else { tmp_path.push_back(portion_original); } - //temp_path[0].close(); } portion_original.clear(); } @@ -226,9 +218,8 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, Geom::Path divider_start, double size_divider) +LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, double size_divider) { - std::vector path_on_start = path_on; split(path_on,divider); std::vector tmp_path; Geom::Affine pre = Geom::Translate(-origin); @@ -300,39 +291,29 @@ LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, G } } if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ - split(path_on_start,divider_start); - for (Geom::PathVector::const_iterator path_it_start = path_on_start.begin(); path_it_start != path_on_start.end(); ++path_it_start) { - Geom::Path original_start = *path_it_start; - if (path_it->empty()) { - continue; + Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); + 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(origin,bbox) + (diagonal * 2); + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Ray base_b(divider.pointAt(1), base_point); + if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ + tmp_path_helper[0].close(); + if(tmp_path_helper.size() > 1){ + tmp_path_helper[tmp_path_helper.size()-1].close(); } - - if( Geom::are_near(tmp_path_helper[0].initialPoint(),original_start.initialPoint())){ - Geom::Point A(divider_start.pointAt(1)); - Geom::Point B(divider_start.pointAt(2)); - - Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); - double hyp = Geom::distance(A, B); - double c = (B[0] - A[0]) / hyp; // cos(alpha) - double s = (B[1] - A[1]) / hyp; // sin(alpha) - - Geom::Affine m2(c, -s, s, c, 0.0, 0.0); - Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - - Geom::Affine m = m1.inverse() * m2; - m = m * sca; - m = m * m2.inverse(); - m = m * m1; - original_start.setInitial(tmp_path_helper[0].initialPoint()); - Geom::Path mirror = original_start * m; - mirror = mirror.reverse(); - mirror.setInitial(original_start.finalPoint()); - original_start.append(mirror); - original_start = original_start.reverse(); - original_start.setFinal(tmp_path_helper[0].initialPoint()); - original_start.append(tmp_path_helper[0]); - tmp_path_helper[0] = original_start; + } else if(Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)){ + tmp_path_helper[0].close(); + if(tmp_path_helper.size() > 1){ + tmp_path_helper[tmp_path_helper.size()-1].close(); } + } else if((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || + (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))){ + Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + close_path.appendNew((Geom::Point)origin); + close_path.appendNew(tmp_path_helper[0].initialPoint()); + tmp_path_helper[0].append(close_path); } } @@ -351,7 +332,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1) { + if(num_copies == 1 && !fusion_paths) { return pwd2_in; } @@ -365,10 +346,6 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Geom::Path divider = Geom::Path(line_start); divider.appendNew((Geom::Point)origin); divider.appendNew(line_end); - Geom::Point line_oposite = origin + dir * Rotate(-deg_to_rad((rotation_angle * num_copies /2)+starting_angle + 180)) * size_divider; - Geom::Path divider_start = Geom::Path(line_start); - divider_start.appendNew((Geom::Point)origin); - divider_start.appendNew(line_oposite); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusion_paths) { @@ -393,7 +370,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p original.close(true); } tmp_path.push_back(original); - setFusion(tmp_path,divider, divider_start, size_divider); + setFusion(tmp_path, divider, size_divider); path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 02141b359..b230a6fc9 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,7 +38,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(std::vector &path_in, Geom::Path divider, Geom::Path divider_start, double sizeDivider); + virtual void setFusion(std::vector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); -- cgit v1.2.3 From e9e6116349cc51e31ae3a643a89644aa4e817b0a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Jun 2015 22:21:35 +0200 Subject: fix minor bug (bzr r13708.1.36) --- src/live_effects/lpe-copy_rotate.cpp | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index d12c03f7e..cfc1b92cf 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -110,7 +110,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if(copies_to_360 ) { + if( copies_to_360 ) { rotation_angle.param_set_value(360.0/(double)num_copies); } if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ @@ -181,16 +181,18 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) for(unsigned int i = 0; i < crossed.size(); i++) { double timeEnd = crossed[i]; Geom::Path portion_original = original.portion(time_start,timeEnd); - Geom::Point side_checker = portion_original.pointAt(0.001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(rotation_angle != 180) { - position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); - } - if(position == 1) { - tmp_path.push_back(portion_original); + if(!portion_original.empty()){ + Geom::Point side_checker = portion_original.pointAt(0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); + if(rotation_angle != 180) { + position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + } + if(position == 1) { + tmp_path.push_back(portion_original); + } + portion_original.clear(); + time_start = timeEnd; } - portion_original.clear(); - time_start = timeEnd; } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); if(rotation_angle != 180) { @@ -198,18 +200,20 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } if(cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); - if (!original.closed()) { - tmp_path.push_back(portion_original); - } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { - portion_original.setFinal(tmp_path[0].initialPoint()); - portion_original.append(tmp_path[0]); - tmp_path[0] = portion_original; - } else { + if(!portion_original.empty()){ + if (!original.closed()) { tmp_path.push_back(portion_original); + } else { + if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + portion_original.setFinal(tmp_path[0].initialPoint()); + portion_original.append(tmp_path[0]); + tmp_path[0] = portion_original; + } else { + tmp_path.push_back(portion_original); + } } + portion_original.clear(); } - portion_original.clear(); } if(cs.size()==0 && position == 1) { tmp_path.push_back(original); -- cgit v1.2.3 From 713ebbaf2d2961951d599543cff3b3cae721955c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 25 Jul 2015 00:19:48 +0200 Subject: fixes for update to trunk (bzr r13708.1.38) --- src/live_effects/lpe-copy_rotate.cpp | 32 ++++++++++++++++---------------- src/live_effects/lpe-copy_rotate.h | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index cfc1b92cf..083f56be8 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -166,9 +166,9 @@ LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Ge } void -LPECopyRotate::split(std::vector &path_on,Geom::Path divider) +LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) { - std::vector tmp_path; + Geom::PathVector tmp_path; double time_start = 0.0; Geom::Path original = path_on[0]; int position = 0; @@ -222,17 +222,17 @@ LPECopyRotate::split(std::vector &path_on,Geom::Path divider) } void -LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, double size_divider) +LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double size_divider) { split(path_on,divider); - std::vector tmp_path; + Geom::PathVector tmp_path; Geom::Affine pre = Geom::Translate(-origin); for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { Geom::Path original = *path_it; if (path_it->empty()) { continue; } - std::vector tmp_path_helper; + Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); @@ -258,35 +258,35 @@ LPECopyRotate::setFusion(std::vector &path_on, Geom::Path divider, d } append_path *= m; if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { - Geom::Path tmp_append = append_path.reverse(); + Geom::Path tmp_append = append_path.reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reverse(); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + Geom::Path tmp_append = append_path.reversed(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reverse(); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reverse(); + Geom::Path tmp_append = append_path.reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); tmp_path_helper[0].append(tmp_append); } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); tmp_path_helper[0].append(tmp_append); - tmp_path_helper[0] = tmp_path_helper[0].reverse(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); } else { tmp_path_helper.push_back(append_path); } @@ -353,8 +353,8 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p Piecewise > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); if(fusion_paths) { - std::vector path_out; - std::vector tmp_path; + Geom::PathVector path_out; + Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) { diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index b230a6fc9..e45fa6d37 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -38,13 +38,13 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(std::vector &path_in, Geom::Path divider, double sizeDivider); + virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); - virtual void split(std::vector &path_in,Geom::Path divider); + virtual void split(Geom::PathVector &path_in,Geom::Path divider); virtual void resetDefaults(SPItem const* item); -- cgit v1.2.3 From 235b6bd52fd472cbc18224d4724961c70fd6214f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Mar 2016 18:34:24 +0100 Subject: Fix order LPE (bzr r13708.1.41) --- src/live_effects/effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index c8696ea3a..2e811ed37 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -144,13 +144,13 @@ const Util::EnumData LPETypeData[] = { {BSPLINE, N_("BSpline"), "bspline"}, {JOIN_TYPE, N_("Join type"), "join_type"}, {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, + {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, /* Ponyscape -> Inkscape 0.92*/ {ATTACH_PATH, N_("Attach path"), "attach_path"}, {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, - {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); -- cgit v1.2.3 From 1bd6284551204ec5b44775a27069595366742ac9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Mar 2016 23:56:39 +0100 Subject: Fix compiling bugs (bzr r13708.1.42) --- src/live_effects/lpe-copy_rotate.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index c60de961d..a16a21bf0 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -93,7 +93,7 @@ void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { if(fusion_paths) { - Geom::Coord angle = Geom::rad_to_deg(atan(-postmul[1]/postmul[0])); + Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); } @@ -235,11 +235,11 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { - Geom::Rotate rot(-Geom::deg_to_rad(rotation_angle * (i))); + Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if(i%2 != 0) { Geom::Point A = (Geom::Point)origin; - Geom::Point B = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle*i)+starting_angle)) * size_divider; + Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) @@ -299,7 +299,7 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s 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(origin,bbox) + (diagonal * 2); - Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::deg_to_rad((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; Geom::Ray base_b(divider.pointAt(1), base_point); if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ tmp_path_helper[0].close(); @@ -343,8 +343,8 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p 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(origin,bbox) + (diagonal * 2); - Geom::Point line_start = origin + dir * Rotate(-deg_to_rad(starting_angle)) * size_divider; - Geom::Point line_end = origin + dir * Rotate(-deg_to_rad(rotation_angle + starting_angle)) * size_divider; + Geom::Point line_start = origin + dir * Rotate(-rad_from_deg(starting_angle)) * size_divider; + Geom::Point line_end = origin + dir * Rotate(-rad_from_deg(rotation_angle + starting_angle)) * size_divider; //Note:: beter way to do this //Whith AppendNew have problems whith the crossing order Geom::Path divider = Geom::Path(line_start); @@ -383,7 +383,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } else { for (int i = 0; i < num_copies; ++i) { - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-rad_from_deg(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } -- cgit v1.2.3 From 67901523e5dc2f6ba839550bd5790fe143c3143e Mon Sep 17 00:00:00 2001 From: raphael0202 Date: Wed, 16 Mar 2016 18:20:29 +0100 Subject: [Bug #1558153] Typos and tabs instead of spaces in extension module. Fixed bugs: - https://launchpad.net/bugs/1558153 (bzr r14713) --- src/extension/implementation/implementation.h | 24 ++++++++++++------------ src/extension/implementation/script.cpp | 18 +++++++++--------- src/extension/init.cpp | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index f6f933aaf..1232ae0c8 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -18,7 +18,7 @@ #include <2geom/forward.h> namespace Gtk { - class Widget; + class Widget; } class SPDocument; @@ -33,7 +33,7 @@ class View; } // namespace UI namespace XML { - class Node; + class Node; } // namespace XML namespace Extension { @@ -51,18 +51,18 @@ namespace Implementation { */ class ImplementationDocumentCache { - /** + /** * The document that this instance is working on. */ - Inkscape::UI::View::View * _view; + Inkscape::UI::View::View * _view; public: - ImplementationDocumentCache (Inkscape::UI::View::View * view) : - _view(view) - { - return; - }; - virtual ~ImplementationDocumentCache ( ) { return; }; - Inkscape::UI::View::View const * view ( ) { return _view; }; + ImplementationDocumentCache (Inkscape::UI::View::View * view) : + _view(view) + { + return; + }; + virtual ~ImplementationDocumentCache ( ) { return; }; + Inkscape::UI::View::View const * view ( ) { return _view; }; }; /** @@ -116,7 +116,7 @@ public: // ----- Effect functions ----- /** Find out information about the file. */ virtual Gtk::Widget * prefs_effect(Inkscape::Extension::Effect *module, - Inkscape::UI::View::View *view, + Inkscape::UI::View::View *view, sigc::signal *changeSignal, ImplementationDocumentCache *docCache); virtual void effect(Inkscape::Extension::Effect * /*module*/, diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 4cb0c9b73..f990598eb 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -152,7 +152,7 @@ Script::Script() : } /** - * brief Destructor + * \brief Destructor */ Script::~Script() { @@ -280,9 +280,9 @@ bool Script::check_existence(const std::string &command) /** \return none - \brief This function 'loads' an extention, basically it determines - the full command for the extention and stores that. - \param module The extention to be loaded. + \brief This function 'loads' an extension, basically it determines + the full command for the extension and stores that. + \param module The extension to be loaded. The most difficult part about this function is finding the actual command through all of the Reprs. Basically it is hidden down a @@ -292,7 +292,7 @@ bool Script::check_existence(const std::string &command) At that point all of the loops are exited, and there is an if statement to make sure they didn't exit because of not finding - the command. If that's the case, the extention doesn't get loaded + the command. If that's the case, the extension doesn't get loaded and should error out at a higher level. */ @@ -545,17 +545,17 @@ SPDocument *Script::open(Inkscape::Extension::Input *module, /** \return none - \brief This function uses an extention to save a document. It first + \brief This function uses an extension to save a document. It first creates an SVG file of the document, and then runs it through the script. - \param module Extention to be used + \param module Extension to be used \param doc Document to be saved \param filename The name to save the final file as \return false in case of any failure writing the file, otherwise true Well, at some point people need to save - it is really what makes the entire application useful. And, it is possible that someone - would want to use an extetion for this, so we need a function to + would want to use an extension for this, so we need a function to do that eh? First things first, the document is saved to a temporary file that @@ -563,7 +563,7 @@ SPDocument *Script::open(Inkscape::Extension::Input *module, ink_ext_ as a prefix. Don't worry, this file gets deleted at the end of the function. - After we have the SVG file, then extention_execute is called with + After we have the SVG file, then Script::execute is called with the temporary file name and the final output filename. This should put the output of the script into the final output file. We then delete the temporary file. diff --git a/src/extension/init.cpp b/src/extension/init.cpp index c16a5a899..af7af2cb1 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -1,6 +1,6 @@ /* * This is what gets executed to initialize all of the modules. For - * the internal modules this invovles executing their initialization + * the internal modules this involves executing their initialization * functions, for external ones it involves reading their .spmodule * files and bringing them into Sodipodi. * -- cgit v1.2.3 From b288e8e5d98684ae81c109a4c4ffa1d25fc4d727 Mon Sep 17 00:00:00 2001 From: raphael0202 Date: Fri, 18 Mar 2016 08:04:08 +0100 Subject: [Bug #1558177] Simplify if conditions in Script.cpp. Fixed bugs: - https://launchpad.net/bugs/1558177 (bzr r14715) --- src/extension/implementation/script.cpp | 6 +----- src/extension/output.cpp | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index f990598eb..2ec17f947 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -232,11 +232,7 @@ bool Script::check_existence(const std::string &command) //Don't search when it is an absolute path. */ if (Glib::path_is_absolute(command)) { - if (Glib::file_test(command, Glib::FILE_TEST_EXISTS)) { - return true; - } else { - return false; - } + return Glib::file_test(command, Glib::FILE_TEST_EXISTS); } // First search in the current directory diff --git a/src/extension/output.cpp b/src/extension/output.cpp index 8de5583c7..83f0fed2f 100644 --- a/src/extension/output.cpp +++ b/src/extension/output.cpp @@ -192,8 +192,7 @@ Output::prefs (void) delete dialog; - if (response == Gtk::RESPONSE_OK) return true; - return false; + return (response == Gtk::RESPONSE_OK); } /** -- cgit v1.2.3 From fbc8d89437445c1024ab4ef2e838f177f408f9f1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 18 Mar 2016 10:16:49 +0100 Subject: Fix writing of 'x' and 'y' attributes in multiline text via sodipode:role="line". (bzr r14716) --- src/sp-text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 4a5b1b1d6..7d4348d19 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -819,8 +819,8 @@ void TextTagAttributes::setFirstXY(Geom::Point &point) attributes.x.resize(1, zero_length); if (attributes.y.empty()) attributes.y.resize(1, zero_length); - attributes.x[0].computed = point[Geom::X]; - attributes.y[0].computed = point[Geom::Y]; + attributes.x[0] = point[Geom::X]; + attributes.y[0] = point[Geom::Y]; } void TextTagAttributes::mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs *output, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_attrs, unsigned parent_attrs_offset, bool copy_xy, bool copy_dxdyrotate) const -- cgit v1.2.3 From 5051da96adc06f2d05c508c2b0ec6ba236d3fdc9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 18 Mar 2016 11:22:38 +0100 Subject: Revert 14707 (bzr r14716.1.1) --- src/widgets/text-toolbar.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 60e932338..c49f0bc05 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -1106,11 +1106,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ lh_unit = unit_table.getUnit("%"); height = query.line_height.value * 100; } else { - //Unit const *active = tracker->getActiveUnit(); - // This allows us to show the unit stored to the user, but right now - // it's always px (because Tav said other units are broken/2016) - lh_unit = unit_table.getUnit(query.line_height.unit); - height = query.line_height.computed; + lh_unit = tracker->getActiveUnit(); + // Can get unit like this: unit_table.getUnit(query.line_height.unit); + height = Inkscape::Util::Quantity::convert(query.line_height.computed, "px", lh_unit); } // Set before value is set -- cgit v1.2.3 From a714c688d60a3a62114591984f57f26cd41dbed9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 18 Mar 2016 11:23:29 +0100 Subject: Reverting 14701. (bzr r14716.1.2) --- src/desktop-style.cpp | 8 +-- src/libnrtype/Layout-TNG.cpp | 2 +- src/sp-text.cpp | 9 +++ src/style.cpp | 4 +- src/ui/widget/unit-tracker.cpp | 10 --- src/ui/widget/unit-tracker.h | 1 - src/util/units.cpp | 70 ++++-------------- src/util/units.h | 8 --- src/widgets/select-toolbar.cpp | 159 ++++++++++++++++++++++------------------- src/widgets/text-toolbar.cpp | 81 ++++----------------- src/widgets/toolbox.cpp | 6 -- 11 files changed, 125 insertions(+), 233 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index d10c75cd8..7f9670af3 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1049,7 +1049,6 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r double letterspacing_prev = 0; double wordspacing_prev = 0; double linespacing_prev = 0; - int linespacing_unit = 0; int texts = 0; int no_size = 0; @@ -1106,11 +1105,6 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r linespacing_current = style->line_height.computed; linespacing_normal = false; } - if (linespacing_unit == 0) { - linespacing_unit = style->line_height.unit; - } else if (linespacing_unit != style->line_height.unit) { - linespacing_unit = SP_CSS_UNIT_PERCENT; - } linespacing += linespacing_current; if ((size_prev != 0 && style->font_size.computed != size_prev) || @@ -1154,7 +1148,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r style_res->line_height.normal = linespacing_normal; style_res->line_height.computed = linespacing; style_res->line_height.value = linespacing; - style_res->line_height.unit = linespacing_unit; + style_res->line_height.unit = SP_CSS_UNIT_PERCENT; if (texts > 1) { if (different) { diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp index ec488b584..8b0889188 100644 --- a/src/libnrtype/Layout-TNG.cpp +++ b/src/libnrtype/Layout-TNG.cpp @@ -14,7 +14,7 @@ namespace Inkscape { namespace Text { const gunichar Layout::UNICODE_SOFT_HYPHEN = 0x00AD; -const double Layout::LINE_HEIGHT_NORMAL = 125; +const double Layout::LINE_HEIGHT_NORMAL = 1.25; Layout::Layout() : _input_truncated(0), diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 7d4348d19..da92ad8d4 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -302,6 +302,15 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X this->attributes.writeTo(repr); this->rebuildLayout(); // copied from update(), see LP Bug 1339305 + // deprecated attribute, but keep it around for backwards compatibility + if (this->style->line_height.set && !this->style->line_height.inherit && !this->style->line_height.normal && this->style->line_height.unit == SP_CSS_UNIT_PERCENT) { + Inkscape::SVGOStringStream os; + os << (this->style->line_height.value * 100.0) << "%"; + this->getRepr()->setAttribute("sodipodi:linespacing", os.str().c_str()); + } else { + this->getRepr()->setAttribute("sodipodi:linespacing", NULL); + } + // SVG 2 Auto-wrapped text if( this->width.computed > 0.0 ) { sp_repr_set_svg_double(repr, "width", this->width.computed); diff --git a/src/style.cpp b/src/style.cpp index 99beaed22..35138d25b 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -113,7 +113,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_weight( "font-weight", enum_font_weight, SP_CSS_FONT_WEIGHT_NORMAL, SP_CSS_FONT_WEIGHT_400 ), font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), font_size(), - line_height( "line-height", 125 ), // SPILengthOrNormal + line_height( "line-height", 1.25 ), // SPILengthOrNormal font_family( "font-family", "sans-serif" ), // SPIString w/default font(), // SPIFont font_specification( "-inkscape-font-specification" ), // SPIString @@ -1957,7 +1957,7 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) sp_css_attr_scale_property_single(css, "kerning", ex); sp_css_attr_scale_property_single(css, "letter-spacing", ex); sp_css_attr_scale_property_single(css, "word-spacing", ex); - //sp_css_attr_scale_property_single(css, "line-height", ex, true); + sp_css_attr_scale_property_single(css, "line-height", ex, true); return css; } diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp index a1501c229..c6318db25 100644 --- a/src/ui/widget/unit-tracker.cpp +++ b/src/ui/widget/unit-tracker.cpp @@ -12,7 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "style-internal.h" #include "unit-tracker.h" #include "widgets/ege-select-one-action.h" @@ -122,15 +121,6 @@ void UnitTracker::addUnit(Inkscape::Util::Unit const *u) gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); } -void UnitTracker::prependUnit(Inkscape::Util::Unit const *u) -{ - GtkTreeIter iter; - gtk_list_store_prepend(_store, &iter); - gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); - /* Re-shuffle our default selection here (_active gets out of sync) */ - setActiveUnit(_activeUnit); -} - void UnitTracker::setFullVal(GtkAdjustment *adj, gdouble val) { _priorValues[adj] = val; diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h index 0fe5bda80..06245930e 100644 --- a/src/ui/widget/unit-tracker.h +++ b/src/ui/widget/unit-tracker.h @@ -42,7 +42,6 @@ public: Inkscape::Util::Unit const * getActiveUnit() const; void addUnit(Inkscape::Util::Unit const *u); - void prependUnit(Inkscape::Util::Unit const *u); void addAdjustment(GtkAdjustment *adj); void setFullVal(GtkAdjustment *adj, gdouble val); diff --git a/src/util/units.cpp b/src/util/units.cpp index 2e7a3b1d2..2c72ec3ae 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -81,21 +81,7 @@ unsigned const svg_length_lookup[] = { UNIT_CODE_PERCENT }; -/* From SP_CSS_UNIT_* to unit */ -unsigned const sp_css_unit_lookup[] = { - 0, - UNIT_CODE_PX, - UNIT_CODE_PT, - UNIT_CODE_PC, - UNIT_CODE_MM, - UNIT_CODE_CM, - UNIT_CODE_IN, - UNIT_CODE_EM, - UNIT_CODE_EX, - UNIT_CODE_PERCENT - // UNIT_CODE_FT Missing, - // UNIT_CODE_MT Missing, -}; + // maps unit codes obtained from their abbreviations to their SVGLength unit indexes typedef INK_UNORDERED_MAP UnitCodeLookup; @@ -227,10 +213,6 @@ bool Unit::compatibleWith(Glib::ustring const &u) const { return compatibleWith(unit_table.getUnit(u)); } -bool Unit::compatibleWith(char const *u) const -{ - return compatibleWith(unit_table.getUnit(u)); -} bool Unit::operator==(Unit const &other) const { @@ -249,29 +231,7 @@ int Unit::svgUnit() const return 0; } -double Unit::convert(double from_dist, Unit const *to) const -{ - // Percentage - if (to->type == UNIT_TYPE_DIMENSIONLESS) { - return from_dist * to->factor; - } - - // Incompatible units - if (type != to->type) { - return -1; - } - - // Compatible units - return from_dist * factor / to->factor; -} -double Unit::convert(double from_dist, Glib::ustring const &to) const -{ - return convert(from_dist, unit_table.getUnit(to)); -} -double Unit::convert(double from_dist, char const *to) const -{ - return convert(from_dist, unit_table.getUnit(to)); -} + Unit UnitTable::_empty_unit; @@ -323,19 +283,6 @@ Unit const *UnitTable::getUnit(SVGLength::Unit u) const } return &_empty_unit; } -/* SP_CSS_UNIT lookup */ -Unit const *UnitTable::getUnit(unsigned int u) const -{ - if (u == 0 || u > 9) { - return &_empty_unit; - } - - UnitCodeMap::const_iterator f = _unit_map.find(sp_css_unit_lookup[u]); - if (f != _unit_map.end()) { - return &(*f->second); - } - return &_empty_unit; -} Unit const *UnitTable::findUnit(double factor, UnitType type) const { @@ -558,7 +505,18 @@ Glib::ustring Quantity::string() const { double Quantity::convert(double from_dist, Unit const *from, Unit const *to) { - return from->convert(from_dist, to); + // Percentage + if (to->type == UNIT_TYPE_DIMENSIONLESS) { + return from_dist * to->factor; + } + + // Incompatible units + if (from->type != to->type) { + return -1; + } + + // Compatible units + return from_dist * from->factor / to->factor; } double Quantity::convert(double from_dist, Glib::ustring const &from, Unit const *to) { diff --git a/src/util/units.h b/src/util/units.h index a840a37ec..13777fd1b 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -75,11 +75,6 @@ public: /** Get SVG unit code. */ int svgUnit() const; - - /** Convert value from this unit **/ - double convert(double from_dist, Unit const *to) const; - double convert(double from_dist, Glib::ustring const &to) const; - double convert(double from_dist, char const *to) const; }; class Quantity @@ -152,9 +147,6 @@ public: /** Retrieve a given unit based on its SVGLength unit */ Unit const *getUnit(SVGLength::Unit u) const; - - /** Retrieve a given unit based on its SP_CSS_UNIT */ - Unit const *getUnit(unsigned int u) const; /** Retrieve a quantity based on its string identifier */ Quantity parseQuantity(Glib::ustring const &q) const; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 3cd6c0e28..e49c4c00a 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -136,13 +136,13 @@ sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection * } static void -sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) +sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) { - if (g_object_get_data(tbl, "update")) { + if (g_object_get_data(G_OBJECT(spw), "update")) { return; } - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); if ( !tracker || tracker->isUpdating() ) { /* * When only units are being changed, don't treat changes @@ -150,7 +150,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) */ return; } - g_object_set_data(tbl, "update", GINT_TO_POINTER(TRUE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = desktop->getSelection(); @@ -168,7 +168,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) Geom::OptRect bbox_user = selection->bounds(bbox_type); if ( !bbox_user ) { - g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } @@ -181,10 +181,10 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); - GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( tbl, "X" ) ); - GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( tbl, "Y" ) ); - GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); - GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); + GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) ); + GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) ); + GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "width" ) ); + GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "height" ) ); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px"); @@ -205,7 +205,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) } // Keep proportions if lock is on - GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "lock") ); + GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; @@ -265,7 +265,68 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) desktop->getCanvas()->endForcedFullRedraws(); } - g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); +} + +static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker ) +{ +#if WITH_GTKMM_3_0 + Glib::RefPtr adj = Glib::wrap(adjustment, true); + Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(adj, climbRate, digits); +#else + Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); +#endif + inkSpinner->addUnitTracker(unit_tracker); + inkSpinner = Gtk::manage( inkSpinner ); + GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); + return widget; +} + +// TODO create_adjustment_action appears to be a rogue tile copy from toolbox.cpp. Resolve it to be unified: + +static EgeAdjustmentAction * create_adjustment_action( gchar const *name, + gchar const *label, + gchar const *shortLabel, + gchar const *data, + gdouble lower, + GtkWidget* focusTarget, + UnitTracker* tracker, + GtkWidget* spw, + gchar const *tooltip, + gboolean altx ) +{ + static bool init = false; + if ( !init ) { + init = true; + ege_adjustment_action_set_compact_tool_factory( createCustomSlider ); + } + + GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, lower, 1e6, SPIN_STEP, SPIN_PAGE_STEP, 0 ) ); + if (tracker) { + tracker->addAdjustment(adj); + } + if ( spw ) { + g_object_set_data( G_OBJECT(spw), data, adj ); + } + + EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3, tracker ); + if ( shortLabel ) { + g_object_set( act, "short_label", Q_(shortLabel), NULL ); + } + + g_signal_connect( G_OBJECT(adj), "value_changed", G_CALLBACK(sp_object_layout_any_value_changed), spw ); + if ( focusTarget ) { + ege_adjustment_action_set_focuswidget( act, focusTarget ); + } + + if ( altx ) { // this spinbutton will be activated by alt-x + g_object_set( G_OBJECT(act), "self-id", "altx", NULL ); + } + + // Using a cast just to make sure we pass in the right kind of function pointer + g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); + + return act; } // toggle button callbacks and updaters @@ -436,60 +497,21 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // four spinbuttons - eact = create_adjustment_action( - /* name= */ "XAction", - /* label= */ C_("Select toolbar", "X position"), - /* shortLabel= */ C_("Select toolbar", "X:"), - /* tooltip= */ C_("Select toolbar", "Horizontal coordinate of selection"), - /* path= */ "/tools/select/X", - /* def(default) */ 0.0, - /* focusTarget= */ GTK_WIDGET(desktop->canvas), - /* dataKludge= */ G_OBJECT(spw), - /* altx, altx_mark */ TRUE, "altx", - /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - /* descrLabels, descrValues, descrCount */ 0, 0, 0, - /* callback= */ sp_object_layout_any_value_changed, - /* unit_tracker= */ tracker, - /* climb, digits, factor */ SPIN_STEP, 3, 1); - + eact = create_adjustment_action( "XAction", C_("Select toolbar", "X position"), C_("Select toolbar", "X:"), "X", + -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Horizontal coordinate of selection"), TRUE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( - /* name= */ "YAction", - /* label= */ C_("Select toolbar", "Y position"), - /* shortLabel= */ C_("Select toolbar", "Y:"), - /* tooltip= */ C_("Select toolbar", "Vertical coordinate of selection"), - /* path= */ "/tools/select/Y", - /* def(default) */ 0.0, - /* focusTarget= */ GTK_WIDGET(desktop->canvas), - /* dataKludge= */ G_OBJECT(spw), - /* altx, altx_mark */ TRUE, "altx", - /* lower, uppper, step, page */ -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - /* descrLabels, descrValues, descrCount */ 0, 0, 0, - /* callback= */ sp_object_layout_any_value_changed, - /* unit_tracker= */ tracker, - /* climb, digits, factor */ SPIN_STEP, 3, 1); - + eact = create_adjustment_action( "YAction", C_("Select toolbar", "Y position"), C_("Select toolbar", "Y:"), "Y", + -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Vertical coordinate of selection"), FALSE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( - /* name= */ "WidthAction", - /* label= */ C_("Select toolbar", "Width"), - /* shortLabel= */ C_("Select toolbar", "W:"), - /* tooltip= */ C_("Select toolbar", "Width of selection"), - /* path= */ "/tools/select/width", - /* def(default) */ 0.0, - /* focusTarget= */ GTK_WIDGET(desktop->canvas), - /* dataKludge= */ G_OBJECT(spw), - /* altx, altx_mark */ TRUE, "altx", - /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - /* descrLabels, descrValues, descrCount */ 0, 0, 0, - /* callback= */ sp_object_layout_any_value_changed, - /* unit_tracker= */ tracker, - /* climb, digits, factor */ SPIN_STEP, 3, 1); - + eact = create_adjustment_action( "WidthAction", C_("Select toolbar", "Width"), C_("Select toolbar", "W:"), "width", + 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Width of selection"), FALSE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); @@ -506,22 +528,9 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } - eact = create_adjustment_action( - /* name= */ "HeightAction", - /* label= */ C_("Select toolbar", "Height"), - /* shortLabel= */ C_("Select toolbar", "H:"), - /* tooltip= */ C_("Select toolbar", "Height of selection"), - /* path= */ "/tools/select/height", - /* def(default) */ 0.0, - /* focusTarget= */ GTK_WIDGET(desktop->canvas), - /* dataKludge= */ G_OBJECT(spw), - /* altx, altx_mark */ TRUE, "altx", - /* lower, uppper, step, page */ 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - /* descrLabels, descrValues, descrCount */ 0, 0, 0, - /* callback= */ sp_object_layout_any_value_changed, - /* unit_tracker= */ tracker, - /* climb, digits, factor */ SPIN_STEP, 3, 1); - + eact = create_adjustment_action( "HeightAction", C_("Select toolbar", "Height"), C_("Select toolbar", "H:"), "height", + 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Height of selection"), FALSE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index c49f0bc05..5ca92b4c0 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -54,17 +54,12 @@ #include "ui/icon-names.h" #include "ui/tools/text-tool.h" #include "ui/tools/tool-base.h" -#include "ui/widget/unit-tracker.h" -#include "util/units.h" #include "verbs.h" #include "xml/repr.h" using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::Util::Unit; -using Inkscape::Util::unit_table; //#define DEBUG_TEXT @@ -509,14 +504,8 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) { - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - - if ( !tracker || tracker->isUpdating() || g_object_get_data(tbl, "freeze")) { - /* - * When only units are being changed, don't treat changes - * to adjuster values as object changes. - * or quit if run by the _changed callbacks - */ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { return; } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); @@ -525,18 +514,7 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - - gdouble value = gtk_adjustment_get_value(adj); - - Unit const *unit = tracker->getActiveUnit(); - - // Value can only be in px or percent or naked pc (e.g. 0.7 for 70%) - if (unit->abbr != "%") { - value = unit->convert(value, "px"); - unit = unit_table.getUnit("px"); - } - - osfs << value << unit->abbr; + osfs << gtk_adjustment_get_value(adj)*100 << "%"; sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); // Apply line-height to selected objects. @@ -1095,31 +1073,21 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Line height (spacing) double height; - - Unit const *lh_unit; - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - if (query.line_height.normal) { - lh_unit = unit_table.getUnit("%"); - height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100; - } else if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { - lh_unit = unit_table.getUnit("%"); - height = query.line_height.value * 100; + height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; } else { - lh_unit = tracker->getActiveUnit(); - // Can get unit like this: unit_table.getUnit(query.line_height.unit); - height = Inkscape::Util::Quantity::convert(query.line_height.computed, "px", lh_unit); + if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { + height = query.line_height.value; + } else { + height = query.line_height.computed; + } } - // Set before value is set - tracker->setActiveUnit(lh_unit); - GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); GtkAdjustment *lineHeightAdjustment = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); gtk_adjustment_set_value( lineHeightAdjustment, height ); - height = gtk_adjustment_get_value( lineHeightAdjustment ); // Word spacing double wordSpacing; @@ -1322,15 +1290,6 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); -static void destroy_tracker( GObject* obj, gpointer /*user_data*/ ) -{ - UnitTracker *tracker = reinterpret_cast(g_object_get_data(obj, "tracker")); - if ( tracker ) { - delete tracker; - g_object_set_data( obj, "tracker", 0 ); - } -} - // Define all the "widgets" in the toolbar. void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -1629,29 +1588,22 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; - // Add the units menu. - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->prependUnit(unit_table.getUnit("%")); - - g_object_set_data( holder, "tracker", tracker ); - g_signal_connect( holder, "destroy", G_CALLBACK(destroy_tracker), holder ); - EgeAdjustmentAction *eact = create_adjustment_action( "TextLineHeightAction", /* name */ _("Line Height"), /* label */ _("Line:"), /* short label */ - _("Spacing between baselines"), /* tooltip */ + _("Spacing between baselines (times font size)"), /* tooltip */ "/tools/text/lineheight", /* preferences path */ - 125, /* default */ + 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ holder, /* dataKludge */ FALSE, /* set alt-x keyboard shortcut? */ NULL, /* altx_mark */ - 0.0, 1e6, 1.0, 10.0, /* lower, upper, step (arrow up/down), page up/down */ + 0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ labels, values, G_N_ELEMENTS(labels), /* drop down menu */ sp_text_lineheight_value_changed, /* callback */ - tracker, /* unit tracker */ - 1.0, /* step (used?) */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ 2, /* digits to show */ 1.0 /* factor (multiplies default) */ ); @@ -1659,11 +1611,6 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextLineHeightAction", eact ); g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); - - GtkAction* act = tracker->createAction( "TextLineHeightUnitAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act ); - g_object_set_data( holder, "TextLineHeightUnitAction", act ); - } /* Word spacing */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f4d7ebf25..72537f727 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -55,7 +55,6 @@ #include "ui/tools-switch.h" #include "../ui/icon-names.h" #include "../ui/widget/style-swatch.h" -#include "../ui/widget/unit-tracker.h" #include "../verbs.h" #include "../widgets/button.h" #include "../widgets/spinbutton-events.h" @@ -516,7 +515,6 @@ static gchar const * ui_descr = " " " " " " - " " " " " " " " @@ -1124,10 +1122,6 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name, g_object_set_data( dataKludge, prefs->getEntry(path).getEntryName().data(), adj ); } - if (unit_tracker) { - unit_tracker->addAdjustment(adj); - } - // Using a cast just to make sure we pass in the right kind of function pointer g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); -- cgit v1.2.3 From ae7a4f0320d820a6183dde933fba576bc2c9f58f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Mar 2016 18:34:07 +0100 Subject: Bug #1419517 Fix Crash when applying new path effect after deleting pattern of Pattern-along-path LPE Fixed bugs: - https://launchpad.net/bugs/1419517 (bzr r14717) --- src/live_effects/parameter/path.cpp | 7 ++++++- src/sp-object.cpp | 15 +++++++-------- src/ui/tool/path-manipulator.cpp | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index e0369e662..7ea1d465c 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -294,7 +294,12 @@ void PathParam::set_new_value (Geom::PathVector const &newpath, bool write_to_svg) { remove_link(); - _pathvector = newpath; + if (newpath.empty()) { + param_set_and_write_default(); + return; + } else { + _pathvector = newpath; + } must_recalculate_pwd2 = true; if (write_to_svg) { diff --git a/src/sp-object.cpp b/src/sp-object.cpp index db66eb3e6..7dbc51b84 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -958,16 +958,15 @@ void SPObject::readAttr(gchar const *key) //g_assert(object != NULL); //g_assert(SP_IS_OBJECT(object)); g_assert(key != NULL); - //XML Tree being used here. - g_assert(this->getRepr() != NULL); + if (this->getRepr() != NULL ) { + unsigned int keyid = sp_attribute_lookup(key); + if (keyid != SP_ATTR_INVALID) { + /* Retrieve the 'key' attribute from the object's XML representation */ + gchar const *value = this->getRepr()->attribute(key); - unsigned int keyid = sp_attribute_lookup(key); - if (keyid != SP_ATTR_INVALID) { - /* Retrieve the 'key' attribute from the object's XML representation */ - gchar const *value = getRepr()->attribute(key); - - setKeyValue(keyid, value); + setKeyValue(keyid, value); + } } } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f4790c317..3b25439f3 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1492,7 +1492,6 @@ void PathManipulator::_getGeometry() void PathManipulator::_setGeometry() { using namespace Inkscape::LivePathEffect; - if (empty()) return; if (!_lpe_key.empty()) { // copied from nodepath.cpp @@ -1505,6 +1504,7 @@ void PathManipulator::_setGeometry() LIVEPATHEFFECT(_path)->requestModified(SP_OBJECT_MODIFIED_FLAG); } } else { + if (empty()) return; //XML Tree being used here directly while it shouldn't be. if (_path->getRepr()->attribute("inkscape:original-d")) _path->set_original_curve(_spcurve, false, false); -- cgit v1.2.3 From 4596974f9ee43a2f5700e3daa468474179aaa829 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Mar 2016 18:58:10 +0100 Subject: Remove code of a semifixed bug (bzr r14718) --- src/sp-object.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 7dbc51b84..db66eb3e6 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -958,15 +958,16 @@ void SPObject::readAttr(gchar const *key) //g_assert(object != NULL); //g_assert(SP_IS_OBJECT(object)); g_assert(key != NULL); + //XML Tree being used here. - if (this->getRepr() != NULL ) { - unsigned int keyid = sp_attribute_lookup(key); - if (keyid != SP_ATTR_INVALID) { - /* Retrieve the 'key' attribute from the object's XML representation */ - gchar const *value = this->getRepr()->attribute(key); + g_assert(this->getRepr() != NULL); - setKeyValue(keyid, value); - } + unsigned int keyid = sp_attribute_lookup(key); + if (keyid != SP_ATTR_INVALID) { + /* Retrieve the 'key' attribute from the object's XML representation */ + gchar const *value = getRepr()->attribute(key); + + setKeyValue(keyid, value); } } -- cgit v1.2.3 From 56b52d05b683b379bd9711531cc052fc1d7c3ecf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Mar 2016 23:30:57 +0100 Subject: Fix Krzysztof comments on merge proposal (bzr r13708.1.43) --- src/live_effects/lpe-copy_rotate.cpp | 203 +++++++++++++++++++---------------- src/live_effects/lpe-copy_rotate.h | 17 +-- 2 files changed, 109 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index a16a21bf0..83175f3e2 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -44,6 +44,29 @@ public: } // namespace CR +int +pointSideOfLine(Geom::Point const &A, Geom::Point const &B, Geom::Point const &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); +} + +bool +pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3) +{ + //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html + using Geom::X; + using Geom::Y; + double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); + double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; + double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; + double s = t1 + t2; + + return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; +} + + LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), @@ -110,22 +133,22 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); - if( copies_to_360 ) { + if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if(fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0){ + if (fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } - if(fusion_paths && copies_to_360) { + if (fusion_paths && copies_to_360) { num_copies.param_set_increments(2,2); - if((int)num_copies%2 !=0) { + if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); } } else { num_copies.param_set_increments(1,1); } - if(dist_angle_handle < 1.0) { + if (dist_angle_handle < 1.0) { dist_angle_handle = 1.0; } A = Point(boundingbox_X.min(), boundingbox_Y.middle()); @@ -135,7 +158,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; - if( fusion_paths || copies_to_360 ) { + if ( fusion_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -143,30 +166,8 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) item->apply_to_mask(item); } -int -LPECopyRotate::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); -} - -bool -LPECopyRotate::pointInTriangle(Geom::Point p, Geom::Point p1, Geom::Point p2, Geom::Point p3) -{ - //http://totologic.blogspot.com.es/2014/01/accurate-point-in-triangle-test.html - using Geom::X; - using Geom::Y; - double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]); - double t1 = (p[X]*(p3[Y] - p1[Y]) + p[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator; - double t2 = (p[X]*(p2[Y] - p1[Y]) + p[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator; - double s = t1 + t2; - - return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1; -} - void -LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) +LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) { Geom::PathVector tmp_path; double time_start = 0.0; @@ -177,34 +178,34 @@ LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) 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 timeEnd = crossed[i]; - Geom::Path portion_original = original.portion(time_start,timeEnd); - if(!portion_original.empty()){ + std::sort(crossed.begin(), crossed.end()); + for (unsigned int i = 0; i < crossed.size(); i++) { + double time_end = crossed[i]; + Geom::Path portion_original = original.portion(time_start,time_end); + if (!portion_original.empty()) { Geom::Point side_checker = portion_original.pointAt(0.001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); - if(rotation_angle != 180) { + if (rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(position == 1) { + if (position == 1) { tmp_path.push_back(portion_original); } portion_original.clear(); - time_start = timeEnd; + time_start = time_end; } } position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); - if(rotation_angle != 180) { + if (rotation_angle != 180) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } - if(cs.size() > 0 && position == 1) { + if (cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); if(!portion_original.empty()){ if (!original.closed()) { tmp_path.push_back(portion_original); } else { - if(tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { + if (tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { portion_original.setFinal(tmp_path[0].initialPoint()); portion_original.append(tmp_path[0]); tmp_path[0] = portion_original; @@ -215,7 +216,7 @@ LPECopyRotate::split(Geom::PathVector &path_on,Geom::Path divider) portion_original.clear(); } } - if(cs.size()==0 && position == 1) { + if (cs.size()==0 && position == 1) { tmp_path.push_back(original); } path_on = tmp_path; @@ -235,9 +236,11 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::PathVector tmp_path_helper; Geom::Path append_path = original; for (int i = 0; i < num_copies; ++i) { + Geom::Path last_helper; + Geom::Path start_helper; Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); - if(i%2 != 0) { + if (i%2 != 0) { Geom::Point A = (Geom::Point)origin; Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); @@ -257,72 +260,82 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s append_path = original; } append_path *= m; - if(i != 0 && tmp_path_helper.size() > 0 &&( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.finalPoint()))) { - Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reversed(); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); - tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),append_path.finalPoint())) { - Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(tmp_path_helper[0].finalPoint()); - tmp_path_helper[0].append(tmp_append); - } else if(i != 0 && tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].initialPoint(),append_path.initialPoint())) { - Geom::Path tmp_append = append_path; - tmp_path_helper[0] = tmp_path_helper[0].reversed(); - tmp_append.setInitial(tmp_path_helper[0].finalPoint()); - tmp_path_helper[0].append(tmp_append); - tmp_path_helper[0] = tmp_path_helper[0].reversed(); + if (i != 0 && tmp_path_helper.size() > 0) { + last_helper = tmp_path_helper[tmp_path_helper.size()-1]; + start_helper = tmp_path_helper[0]; + if (Geom::are_near(last_helper.finalPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + } else if (Geom::are_near(last_helper.initialPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + last_helper = last_helper.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + last_helper = last_helper.reversed(); + } else if (Geom::are_near(last_helper.finalPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + } else if (Geom::are_near(last_helper.initialPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + last_helper = last_helper.reversed(); + tmp_append.setInitial(last_helper.finalPoint()); + last_helper.append(tmp_append); + last_helper = last_helper.reversed(); + } else if (Geom::are_near(start_helper.finalPoint(), append_path.finalPoint())) { + Geom::Path tmp_append = append_path.reversed(); + tmp_append.setInitial(start_helper.finalPoint()); + start_helper.append(tmp_append); + } else if (Geom::are_near(start_helper.initialPoint(), append_path.initialPoint())) { + Geom::Path tmp_append = append_path; + start_helper = start_helper.reversed(); + tmp_append.setInitial(start_helper.finalPoint()); + start_helper.append(tmp_append); + start_helper = start_helper.reversed(); + } else { + tmp_path_helper.push_back(append_path); + } } else { tmp_path_helper.push_back(append_path); } - if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { - tmp_path_helper[tmp_path_helper.size()-1].close(); + if (tmp_path_helper.size() > 0) { + if ( Geom::are_near(last_helper.finalPoint(),last_helper.initialPoint())) { + last_helper.close(); + } } } - if(rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0){ + if (rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0) { + Geom::Path last_helper = tmp_path_helper[tmp_path_helper.size()-1]; + Geom::Path start_helper = tmp_path_helper[0]; Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); 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(origin,bbox) + (diagonal * 2); Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; Geom::Ray base_b(divider.pointAt(1), base_point); - if(Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)){ - tmp_path_helper[0].close(); - if(tmp_path_helper.size() > 1){ - tmp_path_helper[tmp_path_helper.size()-1].close(); + if (Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(start_helper.finalPoint(),base_a)) { + start_helper.close(); + if (tmp_path_helper.size() > 1) { + last_helper.close(); } - } else if(Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && - Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)){ - tmp_path_helper[0].close(); - if(tmp_path_helper.size() > 1){ - tmp_path_helper[tmp_path_helper.size()-1].close(); + } else if (Geom::are_near(last_helper.initialPoint(),base_b) && + Geom::are_near(last_helper.finalPoint(),base_b)) { + start_helper.close(); + if (tmp_path_helper.size() > 1) { + last_helper.close(); } - } else if((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || - (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))){ - Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + } else if ((Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(last_helper.finalPoint(),base_b)) || + (Geom::are_near(start_helper.initialPoint(),base_b) && Geom::are_near(last_helper.finalPoint(),base_a))) { + Geom::Path close_path = Geom::Path(last_helper.finalPoint()); close_path.appendNew((Geom::Point)origin); - close_path.appendNew(tmp_path_helper[0].initialPoint()); - tmp_path_helper[0].append(close_path); + close_path.appendNew(start_helper.initialPoint()); + start_helper.append(close_path); } } - if(tmp_path_helper.size() > 0 && Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { - tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 0 && Geom::are_near(start_helper.finalPoint(),start_helper.initialPoint())) { + start_helper.close(); } tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); tmp_path_helper.clear(); @@ -336,7 +349,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if(num_copies == 1 && !fusion_paths) { + if (num_copies == 1 && !fusion_paths) { return pwd2_in; } @@ -352,7 +365,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); - if(fusion_paths) { + if (fusion_paths) { Geom::PathVector path_out; Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); @@ -368,7 +381,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p } } Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()) { + if (end_open && path_it->closed()) { original.close(false); original.appendNew( original.initialPoint() ); original.close(true); @@ -378,7 +391,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - if(path_out.size()>0) { + if (path_out.size()>0) { output = paths_to_pw(path_out); } } else { diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index e45fa6d37..077699b80 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -31,25 +31,13 @@ class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); - virtual void doOnApply (SPLPEItem const* lpeitem); - virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); - - virtual bool pointInTriangle(Geom::Point p, Geom::Point p0, Geom::Point p1, Geom::Point p2); - - virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); - virtual void split(Geom::PathVector &path_in,Geom::Path divider); - virtual void resetDefaults(SPItem const* item); - virtual void transform_multiply(Geom::Affine const& postmul, bool set); - /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; friend class CR::KnotHolderEntityRotationAngle; @@ -64,16 +52,13 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam fusion_paths; - + BoolParam fusion_paths ; Geom::Point A; Geom::Point B; Geom::Point dir; - Geom::Point start_pos; Geom::Point rot_pos; double dist_angle_handle; - LPECopyRotate(const LPECopyRotate&); LPECopyRotate& operator=(const LPECopyRotate&); }; -- cgit v1.2.3 From 16a30a307c06154881b9c563cb77309810a15baf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 19 Mar 2016 01:13:27 +0100 Subject: Fix more Krzysztof comments on merge proposal, temporary disable LPE on clip and paths (bzr r13708.1.44) --- src/live_effects/lpe-copy_rotate.cpp | 147 ++++++++++++++++++----------------- src/live_effects/lpe-copy_rotate.h | 4 +- 2 files changed, 77 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 83175f3e2..f204f8608 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -74,7 +74,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - fusion_paths(_("Fusioned paths"), _("Fusion paths by helper line"), "fusion_paths", &wr, this, false), + fuse_paths(_("Fuse paths"), _("Fuse paths by helper line"), "fuse_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -83,7 +83,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copies_to_360); - registerParameter(&fusion_paths); + registerParameter(&fuse_paths); registerParameter(&starting_angle); registerParameter(&rotation_angle); registerParameter(&num_copies); @@ -115,7 +115,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) void LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set) { - if(fusion_paths) { + if(fuse_paths) { Geom::Coord angle = Geom::deg_from_rad(atan(-postmul[1]/postmul[0])); angle += starting_angle; starting_angle.param_set_value(angle); @@ -136,10 +136,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) if (copies_to_360) { rotation_angle.param_set_value(360.0/(double)num_copies); } - if (fusion_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { + if (fuse_paths && rotation_angle * num_copies > 360 && rotation_angle > 0) { num_copies.param_set_value(floor(360/rotation_angle)); } - if (fusion_paths && copies_to_360) { + if (fuse_paths && copies_to_360) { num_copies.param_set_increments(2,2); if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); @@ -158,7 +158,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; - if ( fusion_paths || copies_to_360 ) { + if ( fuse_paths || copies_to_360 ) { rot_pos = origin; } SPLPEItem * item = const_cast(lpeitem); @@ -235,9 +235,8 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s } Geom::PathVector tmp_path_helper; Geom::Path append_path = original; + for (int i = 0; i < num_copies; ++i) { - Geom::Path last_helper; - Geom::Path start_helper; Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); Geom::Affine m = pre * rot * Geom::Translate(origin); if (i%2 != 0) { @@ -251,8 +250,8 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s Geom::Affine m2(c, -s, s, c, 0.0, 0.0); Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); - Geom::Affine tmpM = m1.inverse() * m2; - m = tmpM; + Geom::Affine tmp_m = m1.inverse() * m2; + m = tmp_m; m = m * sca; m = m * m2.inverse(); m = m * m1; @@ -260,82 +259,86 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s append_path = original; } append_path *= m; - if (i != 0 && tmp_path_helper.size() > 0) { - last_helper = tmp_path_helper[tmp_path_helper.size()-1]; - start_helper = tmp_path_helper[0]; - if (Geom::are_near(last_helper.finalPoint(), append_path.finalPoint())) { + if (tmp_path_helper.size() > 0) { + if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - } else if (Geom::are_near(last_helper.initialPoint(), append_path.initialPoint())) { + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - last_helper = last_helper.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - last_helper = last_helper.reversed(); - } else if (Geom::are_near(last_helper.finalPoint(), append_path.initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - } else if (Geom::are_near(last_helper.initialPoint(), append_path.finalPoint())) { + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - last_helper = last_helper.reversed(); - tmp_append.setInitial(last_helper.finalPoint()); - last_helper.append(tmp_append); - last_helper = last_helper.reversed(); - } else if (Geom::are_near(start_helper.finalPoint(), append_path.finalPoint())) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); + } else if (Geom::are_near(tmp_path_helper[0].finalPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); - tmp_append.setInitial(start_helper.finalPoint()); - start_helper.append(tmp_append); - } else if (Geom::are_near(start_helper.initialPoint(), append_path.initialPoint())) { + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + } else if (Geom::are_near(tmp_path_helper[0].initialPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; - start_helper = start_helper.reversed(); - tmp_append.setInitial(start_helper.finalPoint()); - start_helper.append(tmp_append); - start_helper = start_helper.reversed(); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); + tmp_append.setInitial(tmp_path_helper[0].finalPoint()); + tmp_path_helper[0].append(tmp_append); + tmp_path_helper[0] = tmp_path_helper[0].reversed(); } else { tmp_path_helper.push_back(append_path); } + if ( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } } else { tmp_path_helper.push_back(append_path); } - if (tmp_path_helper.size() > 0) { - if ( Geom::are_near(last_helper.finalPoint(),last_helper.initialPoint())) { - last_helper.close(); - } - } } - if (rotation_angle * num_copies != 360 && tmp_path_helper.size() > 0) { - Geom::Path last_helper = tmp_path_helper[tmp_path_helper.size()-1]; - Geom::Path start_helper = tmp_path_helper[0]; - Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); - 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(origin,bbox) + (diagonal * 2); - Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; - Geom::Ray base_b(divider.pointAt(1), base_point); - if (Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(start_helper.finalPoint(),base_a)) { - start_helper.close(); - if (tmp_path_helper.size() > 1) { - last_helper.close(); - } - } else if (Geom::are_near(last_helper.initialPoint(),base_b) && - Geom::are_near(last_helper.finalPoint(),base_b)) { - start_helper.close(); - if (tmp_path_helper.size() > 1) { - last_helper.close(); + if (tmp_path_helper.size() > 0) { + tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1]; + tmp_path_helper[0] = tmp_path_helper[0]; + if (rotation_angle * num_copies != 360) { + Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); + 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(origin,bbox) + (diagonal * 2); + Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; + Geom::Ray base_b(divider.pointAt(1), base_point); + if (Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && + Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)) + { + tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 1) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } + } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) + { + tmp_path_helper[0].close(); + if (tmp_path_helper.size() > 1) { + tmp_path_helper[tmp_path_helper.size()-1].close(); + } + } else if ((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || + (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && + Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))) + { + Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); + close_path.appendNew((Geom::Point)origin); + close_path.appendNew(tmp_path_helper[0].initialPoint()); + tmp_path_helper[0].append(close_path); } - } else if ((Geom::are_near(start_helper.initialPoint(),base_a) && Geom::are_near(last_helper.finalPoint(),base_b)) || - (Geom::are_near(start_helper.initialPoint(),base_b) && Geom::are_near(last_helper.finalPoint(),base_a))) { - Geom::Path close_path = Geom::Path(last_helper.finalPoint()); - close_path.appendNew((Geom::Point)origin); - close_path.appendNew(start_helper.initialPoint()); - start_helper.append(close_path); } - } - if (tmp_path_helper.size() > 0 && Geom::are_near(start_helper.finalPoint(),start_helper.initialPoint())) { - start_helper.close(); + if (Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { + tmp_path_helper[0].close(); + } } tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); tmp_path_helper.clear(); @@ -349,7 +352,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p { using namespace Geom; - if (num_copies == 1 && !fusion_paths) { + if (num_copies == 1 && !fuse_paths) { return pwd2_in; } @@ -365,7 +368,7 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise > const & p divider.appendNew(line_end); Piecewise > output; Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); - if (fusion_paths) { + if (fuse_paths) { Geom::PathVector path_out; Geom::PathVector tmp_path; PathVector const original_pathv = path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 077699b80..87af867df 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -35,7 +35,7 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider); - virtual void split(Geom::PathVector &path_in,Geom::Path divider); + virtual void split(Geom::PathVector &path_in, Geom::Path const ÷r); virtual void resetDefaults(SPItem const* item); virtual void transform_multiply(Geom::Affine const& postmul, bool set); /* the knotholder entity classes must be declared friends */ @@ -52,7 +52,7 @@ private: ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copies_to_360; - BoolParam fusion_paths ; + BoolParam fuse_paths; Geom::Point A; Geom::Point B; Geom::Point dir; -- cgit v1.2.3 From 05b3344e7b4151a0ef334ed34c5b566801094806 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 19 Mar 2016 12:17:59 +0100 Subject: Fix a problem with LPE on clips and paths making extremly slow on LPE (bzr r14719) --- src/live_effects/effect.cpp | 4 ++++ src/sp-lpe-item.cpp | 21 ++++++++------------- src/sp-lpe-item.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 38d59a43a..deed7a0a1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -467,6 +467,10 @@ void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) pathvector_before_effect = sp_curve->get_pathvector(); } doBeforeEffect(lpeitem); + if (apply_to_clippath_and_mask && SP_IS_GROUP(sp_lpe_item)) { + sp_lpe_item->apply_to_clippath(sp_lpe_item); + sp_lpe_item->apply_to_mask(sp_lpe_item); + } } /** diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e2afbb55b..fdc2949d5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -209,7 +209,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape /** * returns true when LPE was successful. */ -bool SPLPEItem::performPathEffect(SPCurve *curve, bool clip_paths) { +bool SPLPEItem::performPathEffect(SPCurve *curve, bool is_clip_or_mask) { if (!this) { return false; } @@ -217,7 +217,6 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool clip_paths) { if (!curve) { return false; } - bool apply_to_clippath_and_mask = false; if (this->hasPathEffect() && this->pathEffectsEnabled()) { for (PathEffectList::iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) { @@ -237,17 +236,13 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool clip_paths) { g_warning("SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!"); return false; } - if (lpe->isVisible()) { - if(lpe->apply_to_clippath_and_mask){ - apply_to_clippath_and_mask = true; - } if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished // yet, we don't alter the path return false; } - if (clip_paths || lpe->apply_to_clippath_and_mask) { + if (!is_clip_or_mask || (is_clip_or_mask && lpe->apply_to_clippath_and_mask)) { // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { lpe->doBeforeEffect_impl(this); @@ -270,10 +265,10 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, bool clip_paths) { } } } - } - if(apply_to_clippath_and_mask && clip_paths){ - this->apply_to_clippath((SPItem *)this); - this->apply_to_mask((SPItem *)this); + if(!SP_IS_GROUP(this) && !is_clip_or_mask){ + this->apply_to_clippath(this); + this->apply_to_mask(this); + } } return true; } @@ -698,10 +693,10 @@ SPLPEItem::apply_to_clip_or_mask(SPItem *clip_mask, SPItem *item) try { if(SP_IS_GROUP(this)){ c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); - success = this->performPathEffect(c, false); + success = this->performPathEffect(c, true); c->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { - success = this->performPathEffect(c, false); + success = this->performPathEffect(c, true); } } catch (std::exception & e) { g_warning("Exception during LPE execution. \n %s", e.what()); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index d5e868b2e..9e5cb3329 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -69,7 +69,7 @@ public: virtual void update_patheffect(bool write); - bool performPathEffect(SPCurve *curve, bool clip_paths = true); + bool performPathEffect(SPCurve *curve, bool is_clip_or_mask = false); bool pathEffectsEnabled() const; bool hasPathEffect() const; -- cgit v1.2.3 From 2ab92c531add6a786d4a9cacf41ce33381c2ffe2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 19 Mar 2016 22:42:23 -0400 Subject: Add Shift+Enter path complete and larger square node on mouse over. (bzr r14721) --- src/ui/draw-anchor.cpp | 9 +++++++-- src/ui/tools/pen-tool.cpp | 14 +++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp index 6b9a88ed7..e5a7a493e 100644 --- a/src/ui/draw-anchor.cpp +++ b/src/ui/draw-anchor.cpp @@ -26,6 +26,9 @@ using Inkscape::ControlManager; #define FILL_COLOR_NORMAL 0xffffff7f #define FILL_COLOR_MOUSEOVER 0xff0000ff +#define NODE_SIZE_NORMAL 7.0 +#define NODE_SIZE_MOUSEOVER 10.0 + /** * Creates an anchor object and initializes it. */ @@ -78,14 +81,16 @@ SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool acti if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) { if (!anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL); + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, + "size", NODE_SIZE_MOUSEOVER, NULL); anchor->active = TRUE; } return anchor; } if (anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL); + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, + "size", NODE_SIZE_NORMAL, NULL); anchor->active = FALSE; } return NULL; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 2ed366a7d..ff49417f4 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1220,7 +1220,19 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { case GDK_KEY_KP_Enter: if (this->npoints != 0) { this->ea = NULL; // unset end anchor if set (otherwise crashes) - this->_finish(false); + if(MOD__SHIFT_ONLY(event)) { + // All this is needed to stop the last control + // point dispeating and stop making an n-1 shape. + Geom::Point const event_w(0, 0); + Geom::Point event_dt(desktop->w2d(event_w)); + if(this->red_curve->is_empty()) { + this->red_curve->moveto(event_w); + } + this->_finishSegment(event_w, 0); + this->_finish(true); + } else { + this->_finish(false); + } ret = true; } break; -- cgit v1.2.3 From bb5e99e378d45f0d8cb3db9842a248acc4dadd43 Mon Sep 17 00:00:00 2001 From: suv-lp <> Date: Sun, 20 Mar 2016 09:32:53 +0100 Subject: [Bug #1545332] Canvas context menu: allow grouping a single selection (same as menu, toolbar command). Fixed bugs: - https://launchpad.net/bugs/1545332 (bzr r14723) --- src/ui/interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 69b229519..531aa728d 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -1786,7 +1786,7 @@ void ContextMenu::MakeItemMenu (void) /* Group */ mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup)); - if (_desktop->selection->isEmpty() || _desktop->selection->single()) { + if (_desktop->selection->isEmpty()) { mi->set_sensitive(FALSE); } else { mi->set_sensitive(TRUE); -- cgit v1.2.3 From 7ea0b4c0ca0839a7b837759d2696259e6c91b179 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 20 Mar 2016 14:11:16 +0100 Subject: Add advert tooltip message to copy rotate (bzr r14724) --- src/live_effects/lpe-copy_rotate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index f204f8608..c0c510fa6 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -74,7 +74,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - fuse_paths(_("Fuse paths"), _("Fuse paths by helper line"), "fuse_paths", &wr, this, false), + fuse_paths(_("Fuse paths"), _("Fuse paths by helper line -Use fill rule: evenodd for best result-"), "fuse_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; -- cgit v1.2.3 From fd794a9d8bf0e82e62dfdb75a9f337b361f26b3e Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 20 Mar 2016 09:21:29 -0400 Subject: Update status bar text and remove spare Geom Point variable. (bzr r14725) --- src/ui/tools/pen-tool.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ff49417f4..18af8e105 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1223,12 +1223,11 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { if(MOD__SHIFT_ONLY(event)) { // All this is needed to stop the last control // point dispeating and stop making an n-1 shape. - Geom::Point const event_w(0, 0); - Geom::Point event_dt(desktop->w2d(event_w)); + Geom::Point const p(0, 0); if(this->red_curve->is_empty()) { - this->red_curve->moveto(event_w); + this->red_curve->moveto(p); } - this->_finishSegment(event_w, 0); + this->_finishSegment(p, 0); this->_finish(true); } else { this->_finish(false); @@ -1795,12 +1794,12 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta if (statusbar) { gchar *message = is_curve ? - _("Curve segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path" ): - _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); + _("Curve segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter or Shift+Enter to finish the path" ): + _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter or Shift+Enter to finish the path"); if(this->spiro || this->bspline){ message = is_curve ? - _("Curve segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path" ): - _("Line segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path"); + _("Curve segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter or Shift+Enter to finish the path" ): + _("Line segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter or Shift+Enter to finish the path"); } this->_setAngleDistanceStatusMessage(p, 0, message); } -- cgit v1.2.3 From 504be8ba421045a16c60bd11dbe9e334a1576f0b Mon Sep 17 00:00:00 2001 From: raphael0202 Date: Sun, 20 Mar 2016 17:19:56 +0100 Subject: [Bug #1558160] Move Script::file_listener methods to script.cpp source file. Fixed bugs: - https://launchpad.net/bugs/1558160 (bzr r14727) --- src/extension/implementation/script.cpp | 38 ++++++++++++++++++++++++++++ src/extension/implementation/script.h | 45 +++------------------------------ 2 files changed, 41 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 2ec17f947..9aaf4b952 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -1119,7 +1119,45 @@ int Script::execute (const std::list &in_command, } +void Script::file_listener::init(int fd, Glib::RefPtr main) { + _channel = Glib::IOChannel::create_from_fd(fd); + _channel->set_encoding(); + _conn = main->get_context()->signal_io().connect(sigc::mem_fun(*this, &file_listener::read), _channel, Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR); + _main_loop = main; + return; +} + +bool Script::file_listener::read(Glib::IOCondition condition) { + if (condition != Glib::IO_IN) { + _main_loop->quit(); + return false; + } + + Glib::IOStatus status; + Glib::ustring out; + status = _channel->read_line(out); + _string += out; + + if (status != Glib::IO_STATUS_NORMAL) { + _main_loop->quit(); + _dead = true; + return false; + } + + return true; +} + +bool Script::file_listener::toFile(const Glib::ustring &name) { + try { + Glib::RefPtr stdout_file = Glib::IOChannel::create_from_file(name, "w"); + stdout_file->set_encoding(); + stdout_file->write(_string); + } catch (Glib::FileError &e) { + return false; + } + return true; +} } // namespace Implementation } // namespace Extension diff --git a/src/extension/implementation/script.h b/src/extension/implementation/script.h index 4cf33c989..684719895 100644 --- a/src/extension/implementation/script.h +++ b/src/extension/implementation/script.h @@ -85,49 +85,10 @@ private: }; bool isDead () { return _dead; } - - // TODO move these definitions into script.cpp - void init (int fd, Glib::RefPtr main) { - _channel = Glib::IOChannel::create_from_fd(fd); - _channel->set_encoding(); - _conn = main->get_context()->signal_io().connect(sigc::mem_fun(*this, &file_listener::read), _channel, Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR); - _main_loop = main; - - return; - }; - - bool read (Glib::IOCondition condition) { - if (condition != Glib::IO_IN) { - _main_loop->quit(); - return false; - } - - Glib::IOStatus status; - Glib::ustring out; - status = _channel->read_line(out); - _string += out; - - if (status != Glib::IO_STATUS_NORMAL) { - _main_loop->quit(); - _dead = true; - return false; - } - - return true; - }; - + void init(int fd, Glib::RefPtr main); + bool read(Glib::IOCondition condition); Glib::ustring string (void) { return _string; }; - - bool toFile (const Glib::ustring &name) { - try { - Glib::RefPtr stdout_file = Glib::IOChannel::create_from_file(name, "w"); - stdout_file->set_encoding(); - stdout_file->write(_string); - } catch (Glib::FileError &e) { - return false; - } - return true; - }; + bool toFile(const Glib::ustring &name); }; int execute (const std::list &in_command, -- cgit v1.2.3 From 9f0f6845ee2584b8fdb110db408e66afad5afa26 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 20 Mar 2016 18:22:19 +0100 Subject: Various minor bugfixes to rotate copies (bzr r14728) --- src/live_effects/lpe-copy_rotate.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index c0c510fa6..f07b2c698 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -74,7 +74,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), - fuse_paths(_("Fuse paths"), _("Fuse paths by helper line -Use fill rule: evenodd for best result-"), "fuse_paths", &wr, this, false), + fuse_paths(_("Fuse paths"), _("Fuse paths by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false), dist_angle_handle(100.0) { show_orig_path = true; @@ -143,6 +143,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) num_copies.param_set_increments(2,2); if ((int)num_copies%2 !=0) { num_copies.param_set_value(num_copies+1); + rotation_angle.param_set_value(360.0/(double)num_copies); } } else { num_copies.param_set_increments(1,1); @@ -181,6 +182,9 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) 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){ + continue; + } Geom::Path portion_original = original.portion(time_start,time_end); if (!portion_original.empty()) { Geom::Point side_checker = portion_original.pointAt(0.001); -- cgit v1.2.3 From 400e02890fda98daad1149a13976f0e17567f6fc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 20 Mar 2016 22:51:26 +0100 Subject: Fix a bug in rotate copies on apply over a ellipse when origin and end are the center of rotation (bzr r14729) --- src/live_effects/lpe-copy_rotate.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index f07b2c698..f3e05f061 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -71,8 +71,8 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), - rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), - num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), + rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), + num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), fuse_paths(_("Fuse paths"), _("Fuse paths by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false), dist_angle_handle(100.0) @@ -199,9 +199,10 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) time_start = time_end; } } - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); + Geom::Point side_checker = original.pointAt(original.size() - 0.001); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); if (rotation_angle != 180) { - position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if (cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); -- cgit v1.2.3 From 651e8c239d9aedfb88f31b7d0ace14facbc866d8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 21 Mar 2016 02:02:35 +0100 Subject: Some improvements and bugfixes to rotate copies (bzr r14730) --- src/live_effects/lpe-copy_rotate.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index f3e05f061..d2dd437cb 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -182,12 +182,12 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) 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){ + if (time_start == time_end || time_end - time_start < Geom::EPSILON) { continue; } Geom::Path portion_original = original.portion(time_start,time_end); if (!portion_original.empty()) { - Geom::Point side_checker = portion_original.pointAt(0.001); + Geom::Point side_checker = portion_original.pointAt(0.0001); position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); if (rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); @@ -199,10 +199,9 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) time_start = time_end; } } - Geom::Point side_checker = original.pointAt(original.size() - 0.001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); + position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); if (rotation_angle != 180) { - position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); + position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } if (cs.size() > 0 && position == 1) { Geom::Path portion_original = original.portion(time_start, original.size()); @@ -274,7 +273,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.initialPoint())) { Geom::Path tmp_append = append_path; tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); @@ -284,7 +282,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); - tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); } else if (Geom::are_near(tmp_path_helper[0].finalPoint(), append_path.finalPoint())) { Geom::Path tmp_append = append_path.reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); @@ -294,7 +291,6 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s tmp_path_helper[0] = tmp_path_helper[0].reversed(); tmp_append.setInitial(tmp_path_helper[0].finalPoint()); tmp_path_helper[0].append(tmp_append); - tmp_path_helper[0] = tmp_path_helper[0].reversed(); } else { tmp_path_helper.push_back(append_path); } -- cgit v1.2.3 From f25ef0abb04f72f71fae039c78313cc700818e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bournhonesque?= Date: Tue, 22 Mar 2016 08:41:26 +0100 Subject: Correct typo (bzr r14733) --- src/extension/dbus/document-interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index d64bdbc5c..121a49a25 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -1,7 +1,7 @@ /* * This is where the implementation of the DBus based document API lives. * All the methods in here (except in the helper section) are - * designed to be called remotly via DBus. application-interface.cpp + * designed to be called remotely via DBus. application-interface.cpp * has the methods used to connect to the bus and get a document instance. * * Documentation for these methods is in document-interface.xml -- cgit v1.2.3 From 4cce40a79ab973a3609cd5ee7666673bc2337fef Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 22 Mar 2016 14:56:36 +0100 Subject: Add line-height unit selector to text toolbar. Remove 'm' and 'ft' non-CSS lengths. (bzr r14716.1.3) --- src/desktop-style.cpp | 96 ++++++++++--- src/style.cpp | 3 +- src/svg/svg-length-test.h | 5 +- src/svg/svg-length.cpp | 20 --- src/svg/svg-length.h | 2 - src/ui/widget/preferences-widget.cpp | 4 - src/widgets/text-toolbar.cpp | 256 +++++++++++++++++++++++++++++++++-- src/widgets/toolbox.cpp | 1 + 8 files changed, 320 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 7f9670af3..5f6441aa7 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1036,19 +1036,24 @@ int objects_query_fontnumbers (const std::vector &objects, SPStyle *style_res) { bool different = false; + bool different_lineheight = false; + bool different_lineheight_unit = false; double size = 0; double letterspacing = 0; double wordspacing = 0; - double linespacing = 0; + double lineheight = 0; bool letterspacing_normal = false; bool wordspacing_normal = false; - bool linespacing_normal = false; + bool lineheight_normal = false; + bool lineheight_unit_proportional = false; + bool lineheight_unit_absolute = false; double size_prev = 0; double letterspacing_prev = 0; double wordspacing_prev = 0; - double linespacing_prev = 0; + double lineheight_prev = 0; + int lineheight_unit_prev = -1; int texts = 0; int no_size = 0; @@ -1093,31 +1098,55 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r wordspacing_normal = false; } - double linespacing_current; + // If all line spacing units the same, use that (average line spacing). + // Else if all line spacings absolute, use 'px' (average line spacing). + // Else if all line spacings proportional, use % (average line spacing). + // Else use default. + double lineheight_current; + int lineheight_unit_current; if (style->line_height.normal) { - linespacing_current = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; - if (!different && (linespacing_prev == 0 || linespacing_prev == linespacing_current)) - linespacing_normal = true; - } else if (style->line_height.unit == SP_CSS_UNIT_PERCENT || style->font_size.computed == 0) { - linespacing_current = style->line_height.value; - linespacing_normal = false; + lineheight_current = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + lineheight_unit_current = SP_CSS_UNIT_NONE; + if (!different_lineheight && + (lineheight_prev == 0 || lineheight_prev == lineheight_current)) + lineheight_normal = true; + } else if (style->line_height.unit == SP_CSS_UNIT_NONE || + style->line_height.unit == SP_CSS_UNIT_PERCENT || + style->line_height.unit == SP_CSS_UNIT_EM || + style->line_height.unit == SP_CSS_UNIT_EX || + style->font_size.computed == 0) { + lineheight_current = style->line_height.value; + lineheight_unit_current = style->line_height.unit; + lineheight_unit_proportional = true; + lineheight_normal = false; } else { - linespacing_current = style->line_height.computed; - linespacing_normal = false; + // Always 'px' internally + lineheight_current = style->line_height.computed; + lineheight_unit_current = style->line_height.unit; + lineheight_unit_absolute = true; + lineheight_normal = false; } - linespacing += linespacing_current; + lineheight += lineheight_current; if ((size_prev != 0 && style->font_size.computed != size_prev) || (letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) || - (wordspacing_prev != 0 && style->word_spacing.computed != wordspacing_prev) || - (linespacing_prev != 0 && linespacing_current != linespacing_prev)) { + (wordspacing_prev != 0 && style->word_spacing.computed != wordspacing_prev)) { different = true; } + if (lineheight_prev != 0 && lineheight_current != lineheight_prev) { + different_lineheight = true; + } + + if (lineheight_unit_prev != -1 && lineheight_unit_current != lineheight_unit_prev) { + different_lineheight_unit = true; + } + size_prev = style->font_size.computed; letterspacing_prev = style->letter_spacing.computed; wordspacing_prev = style->word_spacing.computed; - linespacing_prev = linespacing_current; + lineheight_prev = lineheight_current; + lineheight_unit_prev = lineheight_unit_current; // FIXME: we must detect MULTIPLE_DIFFERENT for these too style_res->text_anchor.computed = style->text_anchor.computed; @@ -1133,7 +1162,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r } letterspacing /= texts; wordspacing /= texts; - linespacing /= texts; + lineheight /= texts; } style_res->font_size.computed = size; @@ -1145,13 +1174,36 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r style_res->word_spacing.normal = wordspacing_normal; style_res->word_spacing.computed = wordspacing; - style_res->line_height.normal = linespacing_normal; - style_res->line_height.computed = linespacing; - style_res->line_height.value = linespacing; - style_res->line_height.unit = SP_CSS_UNIT_PERCENT; + style_res->line_height.normal = lineheight_normal; + style_res->line_height.computed = lineheight; + style_res->line_height.value = lineheight; + if (different_lineheight_unit) { + if (lineheight_unit_absolute && !lineheight_unit_proportional) { + // Mixture of absolute units + style_res->line_height.unit = SP_CSS_UNIT_PX; + } else { + // Mixture of relative units + style_res->line_height.unit = SP_CSS_UNIT_PERCENT; + } + if (lineheight_unit_absolute && lineheight_unit_proportional) { + // Mixed types of units, fallback to default + style_res->line_height.computed = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100.0; + style_res->line_height.value = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL * 100.0; + } + } else { + // Same units. + if (lineheight_unit_prev != -1) { + style_res->line_height.unit = lineheight_unit_prev; + } else { + // No text object... use default. + style_res->line_height.unit = SP_CSS_UNIT_NONE; + style_res->line_height.computed = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + style_res->line_height.value = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + } + } if (texts > 1) { - if (different) { + if (different || different_lineheight) { return QUERY_STYLE_MULTIPLE_AVERAGED; } else { return QUERY_STYLE_MULTIPLE_SAME; diff --git a/src/style.cpp b/src/style.cpp index 35138d25b..1f98a50a3 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1510,7 +1510,8 @@ gchar const * sp_style_get_css_unit_string(int unit) { // specify px by default, see inkscape bug 1221626, mozilla bug 234789 - + // This is a problematic fix as some properties (e.g. 'line-height') have + // different behaviour if there is no unit. switch (unit) { case SP_CSS_UNIT_NONE: return "px"; diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h index 0dac4854a..e73211ade 100644 --- a/src/svg/svg-length-test.h +++ b/src/svg/svg-length-test.h @@ -102,10 +102,7 @@ public: for ( int i = (static_cast(SVGLength::NONE) + 1); i <= static_cast(SVGLength::LAST_UNIT); i++ ) { SVGLength::Unit target = static_cast(i); // PX is a special case where we don't have a unit string - // FOOT and MITRE are not CSS/SVG Units - if ( (target != SVGLength::PX) && - (target != SVGLength::FOOT) && - (target != SVGLength::MITRE) ) { + if ( (target != SVGLength::PX) ) { gchar const* val = sp_svg_length_get_css_units(target); TSM_ASSERT_DIFFERS(i, val, ""); } diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index cd995582d..d22da69cd 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -411,14 +411,6 @@ So after the number, the string does not necessarily have a \0 or a unit, it mig *computed = Inkscape::Util::Quantity::convert(v, "in", "px"); } break; - case UVAL('f','t'): - if (unit) { - *unit = SVGLength::FOOT; - } - if (computed) { - *computed = Inkscape::Util::Quantity::convert(v, "ft", "px"); - } - break; case UVAL('e','m'): if (unit) { *unit = SVGLength::EM; @@ -495,12 +487,6 @@ void SVGLength::set(SVGLength::Unit u, float v) case INCH: hack = "pt"; break; - case FOOT: - hack = "pt"; - break; - case MITRE: - hack = "m"; - break; default: break; } @@ -572,8 +558,6 @@ gchar const *sp_svg_length_get_css_units(SVGLength::Unit unit) case SVGLength::MM: return "mm"; case SVGLength::CM: return "cm"; case SVGLength::INCH: return "in"; - case SVGLength::FOOT: return ""; // Not in SVG/CSS specification. - case SVGLength::MITRE: return ""; // Not in SVG/CSS specification. case SVGLength::EM: return "em"; case SVGLength::EX: return "ex"; case SVGLength::PERCENT: return "%"; @@ -590,10 +574,6 @@ std::string sp_svg_length_write_with_units(SVGLength const &length) Inkscape::SVGOStringStream os; if (length.unit == SVGLength::PERCENT) { os << 100*length.value << sp_svg_length_get_css_units(length.unit); - } else if (length.unit == SVGLength::FOOT) { - os << 12*length.value << sp_svg_length_get_css_units(SVGLength::INCH); - } else if (length.unit == SVGLength::MITRE) { - os << 100*length.value << sp_svg_length_get_css_units(SVGLength::CM); } else { os << length.value << sp_svg_length_get_css_units(length.unit); } diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index 2aaf248b1..bd3435ca6 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -27,8 +27,6 @@ public: MM, CM, INCH, - FOOT, - MITRE, EM, EX, PERCENT, diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index e906762e3..d56506d62 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -468,12 +468,8 @@ ZoomCorrRuler::on_draw(const Cairo::RefPtr& cr) { Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit"); if (abbr == "cm") { draw_marks(cr, 0.1, 10); - } else if (abbr == "ft") { - draw_marks(cr, 1/12.0, 12); } else if (abbr == "in") { draw_marks(cr, 0.25, 4); - } else if (abbr == "m") { - draw_marks(cr, 1/10.0, 10); } else if (abbr == "mm") { draw_marks(cr, 10, 10); } else if (abbr == "pc") { diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 5ca92b4c0..8df80d2b6 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -54,12 +54,18 @@ #include "ui/icon-names.h" #include "ui/tools/text-tool.h" #include "ui/tools/tool-base.h" +#include "ui/widget/unit-tracker.h" +#include "util/units.h" #include "verbs.h" #include "xml/repr.h" using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::Util::unit_table; +using Inkscape::UI::Widget::UnitTracker; //#define DEBUG_TEXT @@ -510,25 +516,48 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // At the moment this handles only numerical values (i.e. no percent). + + // Get user selected unit and save as preference + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so + // we can save it (allows us to adjust line height value when unit changes). + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + + // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj)*100 << "%"; + // We should handle unitless values as well as 'em' and 'ex' + if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") { + osfs << gtk_adjustment_get_value(adj) << unit->abbr; + } else { + // Inside SVG file, always use "px" for absolute units. + osfs << Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") << "px"; + } sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + // Apply line-height to selected objects. SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, false); - // Until deprecated sodipodi:linespacing purged: + // Only need to save for undo if a text item has been changed. Inkscape::Selection *selection = desktop->getSelection(); bool modmade = false; std::vector itemlist=selection->itemList(); for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { - (*i)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); modmade = true; } } @@ -554,6 +583,153 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } + +static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // Get old saved unit + int old_unit = GPOINTER_TO_INT( g_object_get_data(tbl, "lineheight_unit")); + + // Get user selected unit and save as preference + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + + // Read current line height value + EgeAdjustmentAction *line_height_act = + reinterpret_cast(g_object_get_data(tbl, "TextLineHeightAction")); + GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act ); + double line_height = gtk_adjustment_get_value(line_height_adj); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = desktop->getSelection(); + std::vector itemlist=selection->itemList(); + + // Convert between units + if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_EX) { + line_height *= 0.5; + } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_EM) { + line_height *= 2.0; + } else if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EM) { + line_height *= 100; + } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 50.0; + } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { + line_height *= 50; + } else if ((unit->abbr) == "%" || (unit->abbr) == "em" || (unit->abbr) == "ex") { + // Convert absolute to relative... for the moment use average font-size + double font_size = 0; + int count = 0; + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i)) { + font_size += (*i)->style->font_size.computed; + ++count; + } + } + if (count > 0) { + font_size /= count; + } else { + font_size = 20; + } + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); + if (font_size > 0) { + line_height /= font_size; + } + if ((unit->abbr) == "%") { + line_height *= 100; + } else if ((unit->abbr) == "ex") { + line_height *= 2; + } + } else if (old_unit==SP_CSS_UNIT_PERCENT || old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) { + // Convert relative to absolute... for the moment use average font-size + double font_size = 0; + int count = 0; + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i)) { + font_size += (*i)->style->font_size.computed; + ++count; + } + } + if (count > 0) { + font_size /= count; + } else { + font_size = 20; + } + line_height *= font_size; + if (old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if (old_unit == SP_CSS_UNIT_EX) { + line_height /= 2.0; + } + line_height = Quantity::convert(line_height, "px", unit); + } else { + // Convert between different absolute units (only used in GUI) + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit); + } + + // Set css line height. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + // We should handle unitless values as well as 'em' and 'ex' + if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") { + osfs << line_height << unit->abbr; + } else { + osfs << Quantity::convert(line_height, unit, "px") << "px"; + } + sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + + // Update GUI with line_height value. + gtk_adjustment_set_value(line_height_adj, line_height); + + // Apply line-height to selected objects. + sp_desktop_set_style (desktop, css, true, false); + + // Only need to save for undo if a text item has been changed. + bool modmade = false; + for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i)) { + modmade = true; + } + } + + // Save for undo + if(modmade) { + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, + _("Text: Change line-height unit")); + } + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) { // quit if run by the _changed callbacks @@ -1064,6 +1240,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ { activeButton = 3; } else { + // This should take 'direction' into account if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; @@ -1071,16 +1248,47 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ ege_select_one_action_set_active( textAlignAction, activeButton ); - // Line height (spacing) + // Line height (spacing) and line height unit double height; + int line_height_unit = -1; if (query.line_height.normal) { + std::cout << " normal" << std::endl; height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + line_height_unit = SP_CSS_UNIT_NONE; } else { - if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { - height = query.line_height.value; - } else { - height = query.line_height.computed; - } + height = query.line_height.value; + line_height_unit = query.line_height.unit; + } + + switch (line_height_unit) { + case SP_CSS_UNIT_NONE: + // tracker can't show no unit... use 'em' + line_height_unit = SP_CSS_UNIT_EM; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + break; + case SP_CSS_UNIT_PERCENT: + height *= 100.0; // Inkscape store % as fraction in .value + break; + case SP_CSS_UNIT_PX: + // If unit is set to 'px', use the preferred display unit (if absolute). + line_height_unit = + prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT); + if (line_height_unit != SP_CSS_UNIT_EM && + line_height_unit != SP_CSS_UNIT_EX && + line_height_unit != SP_CSS_UNIT_PERCENT) { + height = + Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); + } else { + line_height_unit = SP_CSS_UNIT_PX; + } + break; + default: + // If unit has been set by an external program to something other than 'px', use + // that unit. But height is average of computed values (px) so we need to convert + // back. + height = + Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); } GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); @@ -1088,7 +1296,11 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); gtk_adjustment_set_value( lineHeightAdjustment, height ); - + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit)); + // Save unit so we can do convertions between new/old units. + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); + // Word spacing double wordSpacing; if (query.word_spacing.normal) wordSpacing = 0.0; @@ -1231,7 +1443,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ #endif g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - } static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) @@ -1582,6 +1793,15 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_changed), holder ); } + /* Line height unit tracker */ + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->addUnit(unit_table.getUnit("%")); + tracker->addUnit(unit_table.getUnit("em")); + tracker->addUnit(unit_table.getUnit("ex")); + // tracker->addUnit(unit_table.getUnit("None")); + tracker->setActiveUnit(unit_table.getUnit("%")); + g_object_set_data( holder, "tracker", tracker ); + /* Line height */ { // Drop down menu @@ -1599,20 +1819,28 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje holder, /* dataKludge */ FALSE, /* set alt-x keyboard shortcut? */ NULL, /* altx_mark */ - 0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ + 0.0, 1000.0, 1.0, 10.0, /* lower, upper, step (arrow up/down), page up/down */ labels, values, G_N_ELEMENTS(labels), /* drop down menu */ sp_text_lineheight_value_changed, /* callback */ - NULL, /* unit tracker */ + NULL, // tracker, /* unit tracker */ 0.1, /* step (used?) */ 2, /* digits to show */ 1.0 /* factor (multiplies default) */ ); + //tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextLineHeightAction", eact ); g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); } + /* Line height units */ + { + GtkAction* act = tracker->createAction( "TextLineHeightUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_lineheight_unit_changed), holder ); + } + /* Word spacing */ { // Drop down menu diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 72537f727..705c16d1f 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -515,6 +515,7 @@ static gchar const * ui_descr = " " " " " " + " " " " " " " " -- cgit v1.2.3 From 35acdcff45adf06faf74f4f09a9b428aebd1c591 Mon Sep 17 00:00:00 2001 From: Martin Owens <> Date: Tue, 22 Mar 2016 19:56:20 +0100 Subject: Code cleanup. Removal of rogue copy of "create_adjustment_action". (bzr r14736) --- src/widgets/select-toolbar.cpp | 160 ++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index e49c4c00a..9851b0606 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -136,13 +136,13 @@ sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection * } static void -sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) +sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) { - if (g_object_get_data(G_OBJECT(spw), "update")) { + if (g_object_get_data(tbl, "update")) { return; } - UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); if ( !tracker || tracker->isUpdating() ) { /* * When only units are being changed, don't treat changes @@ -150,7 +150,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) */ return; } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + g_object_set_data(tbl, "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = desktop->getSelection(); @@ -168,7 +168,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Geom::OptRect bbox_user = selection->bounds(bbox_type); if ( !bbox_user ) { - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); return; } @@ -181,10 +181,10 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); - GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) ); - GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) ); - GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "width" ) ); - GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "height" ) ); + GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( tbl, "X" ) ); + GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( tbl, "Y" ) ); + GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); + GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px"); @@ -205,7 +205,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) } // Keep proportions if lock is on - GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); + GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; @@ -265,68 +265,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) desktop->getCanvas()->endForcedFullRedraws(); } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); -} - -static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker ) -{ -#if WITH_GTKMM_3_0 - Glib::RefPtr adj = Glib::wrap(adjustment, true); - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(adj, climbRate, digits); -#else - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); -#endif - inkSpinner->addUnitTracker(unit_tracker); - inkSpinner = Gtk::manage( inkSpinner ); - GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); - return widget; -} - -// TODO create_adjustment_action appears to be a rogue tile copy from toolbox.cpp. Resolve it to be unified: - -static EgeAdjustmentAction * create_adjustment_action( gchar const *name, - gchar const *label, - gchar const *shortLabel, - gchar const *data, - gdouble lower, - GtkWidget* focusTarget, - UnitTracker* tracker, - GtkWidget* spw, - gchar const *tooltip, - gboolean altx ) -{ - static bool init = false; - if ( !init ) { - init = true; - ege_adjustment_action_set_compact_tool_factory( createCustomSlider ); - } - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, lower, 1e6, SPIN_STEP, SPIN_PAGE_STEP, 0 ) ); - if (tracker) { - tracker->addAdjustment(adj); - } - if ( spw ) { - g_object_set_data( G_OBJECT(spw), data, adj ); - } - - EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3, tracker ); - if ( shortLabel ) { - g_object_set( act, "short_label", Q_(shortLabel), NULL ); - } - - g_signal_connect( G_OBJECT(adj), "value_changed", G_CALLBACK(sp_object_layout_any_value_changed), spw ); - if ( focusTarget ) { - ege_adjustment_action_set_focuswidget( act, focusTarget ); - } - - if ( altx ) { // this spinbutton will be activated by alt-x - g_object_set( G_OBJECT(act), "self-id", "altx", NULL ); - } - - // Using a cast just to make sure we pass in the right kind of function pointer - g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); - - return act; + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); } // toggle button callbacks and updaters @@ -497,21 +436,60 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // four spinbuttons - eact = create_adjustment_action( "XAction", C_("Select toolbar", "X position"), C_("Select toolbar", "X:"), "X", - -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Horizontal coordinate of selection"), TRUE ); + eact = create_adjustment_action( + "XAction", /* name */ + C_("Select toolbar", "X position"), /* label */ + C_("Select toolbar", "X:"), /* shortLabel */ + C_("Select toolbar", "Horizontal coordinate of selection"), /* tooltip */ + "/tools/select/X", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( "YAction", C_("Select toolbar", "Y position"), C_("Select toolbar", "Y:"), "Y", - -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Vertical coordinate of selection"), FALSE ); + eact = create_adjustment_action( + "YAction", /* name */ + C_("Select toolbar", "Y position"), /* label */ + C_("Select toolbar", "Y:"), /* shortLabel */ + C_("Select toolbar", "Vertical coordinate of selection"), /* tooltip */ + "/tools/select/Y", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); - eact = create_adjustment_action( "WidthAction", C_("Select toolbar", "Width"), C_("Select toolbar", "W:"), "width", - 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Width of selection"), FALSE ); + eact = create_adjustment_action( + "WidthAction", /* name */ + C_("Select toolbar", "Width"), /* label */ + C_("Select toolbar", "W:"), /* shortLabel */ + C_("Select toolbar", "Width of selection"), /* tooltip */ + "/tools/select/width", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); @@ -528,9 +506,23 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } - eact = create_adjustment_action( "HeightAction", C_("Select toolbar", "Height"), C_("Select toolbar", "H:"), "height", - 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, - _("Height of selection"), FALSE ); + eact = create_adjustment_action( + "HeightAction", /* name */ + C_("Select toolbar", "Height"), /* label */ + C_("Select toolbar", "H:"), /* shortLabel */ + C_("Select toolbar", "Height of selection"), /* tooltip */ + "/tools/select/height", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, uppper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); -- cgit v1.2.3 From 41751706dc695123b53136bd4fe3d069f5321337 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 22 Mar 2016 15:10:16 -0400 Subject: Add prependUnit function (bzr r14737) --- src/ui/widget/unit-tracker.cpp | 10 ++++++++++ src/ui/widget/unit-tracker.h | 1 + 2 files changed, 11 insertions(+) (limited to 'src') diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp index c6318db25..a1501c229 100644 --- a/src/ui/widget/unit-tracker.cpp +++ b/src/ui/widget/unit-tracker.cpp @@ -12,6 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "style-internal.h" #include "unit-tracker.h" #include "widgets/ege-select-one-action.h" @@ -121,6 +122,15 @@ void UnitTracker::addUnit(Inkscape::Util::Unit const *u) gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); } +void UnitTracker::prependUnit(Inkscape::Util::Unit const *u) +{ + GtkTreeIter iter; + gtk_list_store_prepend(_store, &iter); + gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1); + /* Re-shuffle our default selection here (_active gets out of sync) */ + setActiveUnit(_activeUnit); +} + void UnitTracker::setFullVal(GtkAdjustment *adj, gdouble val) { _priorValues[adj] = val; diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h index 06245930e..8fa9ff304 100644 --- a/src/ui/widget/unit-tracker.h +++ b/src/ui/widget/unit-tracker.h @@ -43,6 +43,7 @@ public: void addUnit(Inkscape::Util::Unit const *u); void addAdjustment(GtkAdjustment *adj); + void prependUnit(Inkscape::Util::Unit const *u); void setFullVal(GtkAdjustment *adj, gdouble val); GtkAction *createAction(gchar const *name, gchar const *label, gchar const *tooltip); -- cgit v1.2.3 From 66aeeb4707125e2d45ba460f84edfc6516773d7f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 22 Mar 2016 15:10:37 -0400 Subject: Make sure adjustment is attached to spin button (bzr r14738) --- src/widgets/toolbox.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 705c16d1f..3389f82f9 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -55,6 +55,7 @@ #include "ui/tools-switch.h" #include "../ui/icon-names.h" #include "../ui/widget/style-swatch.h" +#include "../ui/widget/unit-tracker.h" #include "../verbs.h" #include "../widgets/button.h" #include "../widgets/spinbutton-events.h" @@ -1123,6 +1124,10 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name, g_object_set_data( dataKludge, prefs->getEntry(path).getEntryName().data(), adj ); } + if (unit_tracker) { + unit_tracker->addAdjustment(adj); + } + // Using a cast just to make sure we pass in the right kind of function pointer g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); -- cgit v1.2.3 From c7d0b04c70397faadf0131ab5d846068f44d5062 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 22 Mar 2016 15:17:52 -0400 Subject: Un-revert: Allow Unit object to do conversions, pipe Quality class method via that. (bzr r14739) --- src/util/units.cpp | 37 +++++++++++++++++++++++++------------ src/util/units.h | 5 +++++ 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/util/units.cpp b/src/util/units.cpp index 2c72ec3ae..cf4bfd146 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -231,6 +231,30 @@ int Unit::svgUnit() const return 0; } +double Unit::convert(double from_dist, Unit const *to) const +{ + // Percentage + if (to->type == UNIT_TYPE_DIMENSIONLESS) { + return from_dist * to->factor; + } + + // Incompatible units + if (type != to->type) { + return -1; + } + + // Compatible units + return from_dist * factor / to->factor; +} +double Unit::convert(double from_dist, Glib::ustring const &to) const +{ + return convert(from_dist, unit_table.getUnit(to)); +} +double Unit::convert(double from_dist, char const *to) const +{ + return convert(from_dist, unit_table.getUnit(to)); +} + Unit UnitTable::_empty_unit; @@ -505,18 +529,7 @@ Glib::ustring Quantity::string() const { double Quantity::convert(double from_dist, Unit const *from, Unit const *to) { - // Percentage - if (to->type == UNIT_TYPE_DIMENSIONLESS) { - return from_dist * to->factor; - } - - // Incompatible units - if (from->type != to->type) { - return -1; - } - - // Compatible units - return from_dist * from->factor / to->factor; + return from->convert(from_dist, to); } double Quantity::convert(double from_dist, Glib::ustring const &from, Unit const *to) { diff --git a/src/util/units.h b/src/util/units.h index 13777fd1b..fa70058ba 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -75,6 +75,11 @@ public: /** Get SVG unit code. */ int svgUnit() const; + + /** Convert value from this unit **/ + double convert(double from_dist, Unit const *to) const; + double convert(double from_dist, Glib::ustring const &to) const; + double convert(double from_dist, char const *to) const; }; class Quantity -- cgit v1.2.3 From 3de7e5dc56d38f9f52575f8ed47334d68e6223ad Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 24 Mar 2016 02:25:49 +0100 Subject: "Backport" some Krzysztof review parts of mirror symmetry LPE also hapens on rotate copies LPE (bzr r14740) --- src/live_effects/lpe-copy_rotate.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index d2dd437cb..efea76039 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -44,14 +44,6 @@ public: } // namespace CR -int -pointSideOfLine(Geom::Point const &A, Geom::Point const &B, Geom::Point const &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); -} - bool pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3) { @@ -188,7 +180,7 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) Geom::Path portion_original = original.portion(time_start,time_end); if (!portion_original.empty()) { Geom::Point side_checker = portion_original.pointAt(0.0001); - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), side_checker); + position = Geom::sgn(Geom::cross(divider[1].finalPoint() - divider[0].finalPoint(), side_checker - divider[0].finalPoint())); if (rotation_angle != 180) { position = pointInTriangle(side_checker, divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } @@ -199,7 +191,7 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) time_start = time_end; } } - position = pointSideOfLine(divider[0].finalPoint(), divider[1].finalPoint(), original.finalPoint()); + position = Geom::sgn(Geom::cross(divider[1].finalPoint() - divider[0].finalPoint(), original.finalPoint() - divider[0].finalPoint())); if (rotation_angle != 180) { position = pointInTriangle(original.finalPoint(), divider.initialPoint(), divider[0].finalPoint(), divider[1].finalPoint()); } @@ -246,13 +238,13 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s if (i%2 != 0) { Geom::Point A = (Geom::Point)origin; Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; - Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); + Geom::Translate m1(A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) double s = (B[1] - A[1]) / hyp; // sin(alpha) Geom::Affine m2(c, -s, s, c, 0.0, 0.0); - Geom::Affine sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); + Geom::Scale sca(1.0, -1.0); Geom::Affine tmp_m = m1.inverse() * m2; m = tmp_m; -- cgit v1.2.3 From 861ad5fe4e858b218e9260011b6f128ec1410e24 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 24 Mar 2016 19:04:10 +0100 Subject: Revert revision #14156 because problems with offsets, see coments added (bzr r14741) --- src/sp-offset.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index 7c3d0bd03..d84bdbdd3 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -83,7 +83,9 @@ static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *i // fast is not mathematically correct, because computing the offset of a single // cubic bezier patch is not trivial; in particular, there are problems with holes // reappearing in offset when the radius becomes too large -static bool use_slow_but_correct_offset_method=true; +//TODO: need fix for bug: #384688 with fix released in r.14156 +//but reverted because bug #1507049 seems has more priority. +static bool use_slow_but_correct_offset_method = false; SPOffset::SPOffset() : SPShape() { this->rad = 1.0; -- cgit v1.2.3 From 401c2f70ce1ffcdf7a041c27df8c06e19f42e847 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 28 Mar 2016 20:49:42 -0400 Subject: Fix bugs with the colour selector self-signaling on change. Fixed bugs: - https://launchpad.net/bugs/1462907 - https://launchpad.net/bugs/1249618 (bzr r14747) --- src/ui/selected-color.cpp | 1 - src/ui/widget/color-wheel-selector.cpp | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/selected-color.cpp b/src/ui/selected-color.cpp index 8c37ee7e0..846d50a5b 100644 --- a/src/ui/selected-color.cpp +++ b/src/ui/selected-color.cpp @@ -139,7 +139,6 @@ void SelectedColor::setHeld(bool held) { if (released) { signal_released.emit(); - signal_changed.emit(); } _updating = false; } diff --git a/src/ui/widget/color-wheel-selector.cpp b/src/ui/widget/color-wheel-selector.cpp index ed3400bb5..cac812640 100644 --- a/src/ui/widget/color-wheel-selector.cpp +++ b/src/ui/widget/color-wheel-selector.cpp @@ -246,21 +246,23 @@ void ColorWheelSelector::_wheelChanged(GimpColorWheel *wheel, ColorWheelSelector guint32 end = color.toRGBA32(0xff); wheelSelector->_slider->setColors(start, mid, end); - wheelSelector->_color.preserveICC(); + wheelSelector->_updating = true; wheelSelector->_color.setHeld(gimp_color_wheel_is_adjusting(wheel)); wheelSelector->_color.setColor(color); + wheelSelector->_updating = false; } void ColorWheelSelector::_updateDisplay() { + if(_updating) { return; } + #ifdef DUMP_CHANGE_INFO g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0], _color.color().v.c[1], _color.color().v.c[2], alpha); #endif - bool oldval = _updating; _updating = true; { float hsv[3] = { 0, 0, 0 }; @@ -276,7 +278,7 @@ void ColorWheelSelector::_updateDisplay() ColorScales::setScaled(_alpha_adjustment->gobj(), _color.alpha()); - _updating = oldval; + _updating = false; } -- cgit v1.2.3 From b2587a888338617bc8482bfc969072b979911719 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 29 Mar 2016 15:54:04 -0400 Subject: Protect the color wheel from hue loss at a deeper level. (bzr r14748) --- src/ui/widget/color-wheel-selector.cpp | 2 +- src/ui/widget/gimpcolorwheel.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/widget/color-wheel-selector.cpp b/src/ui/widget/color-wheel-selector.cpp index cac812640..22c616325 100644 --- a/src/ui/widget/color-wheel-selector.cpp +++ b/src/ui/widget/color-wheel-selector.cpp @@ -245,10 +245,10 @@ void ColorWheelSelector::_wheelChanged(GimpColorWheel *wheel, ColorWheelSelector guint32 mid = color.toRGBA32(0x7f); guint32 end = color.toRGBA32(0xff); + wheelSelector->_updating = true; wheelSelector->_slider->setColors(start, mid, end); wheelSelector->_color.preserveICC(); - wheelSelector->_updating = true; wheelSelector->_color.setHeld(gimp_color_wheel_is_adjusting(wheel)); wheelSelector->_color.setColor(color); wheelSelector->_updating = false; diff --git a/src/ui/widget/gimpcolorwheel.c b/src/ui/widget/gimpcolorwheel.c index f632331d8..c857cfa8a 100644 --- a/src/ui/widget/gimpcolorwheel.c +++ b/src/ui/widget/gimpcolorwheel.c @@ -1412,6 +1412,10 @@ gimp_color_wheel_set_color (GimpColorWheel *wheel, priv = wheel->priv; + if(h == 0.0 && s == 0.0) { + h = priv->h; + } + priv->h = h; priv->s = s; priv->v = v; -- cgit v1.2.3 From b7fbe1182eabcd13d53e1dbcbfcbec93e37f01ee Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Wed, 30 Mar 2016 02:06:26 +0200 Subject: Fix bug #1548953 (Crash when SVG contains certain special chars) Fixed bugs: - https://launchpad.net/bugs/1548953 (bzr r14750) --- src/display/drawing-text.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index a3ca7173a..f0d83abfd 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -100,14 +100,16 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext above and below the max/min y positions of the letters to place the text decorations.*/ Geom::Rect b; - if(_drawable){ - Geom::OptRect tiltb = bounds_exact(*_font->PathVector(_glyph)); - Geom::Rect bigbox(Geom::Point(tiltb->left(),-_dsc*scale_bigbox*1.1),Geom::Point(tiltb->right(),_asc*scale_bigbox*1.1)); - b = bigbox * ctx.ctm; + if (_drawable) { + Geom::OptRect tiltb = bounds_exact(*_font->PathVector(_glyph)); + if (tiltb) { + Geom::Rect bigbox(Geom::Point(tiltb->left(),-_dsc*scale_bigbox*1.1),Geom::Point(tiltb->right(),_asc*scale_bigbox*1.1)); + b = bigbox * ctx.ctm; + } } - else { // Fallback, spaces mostly - Geom::Rect bigbox(Geom::Point(0.0, -_dsc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, _asc*scale_bigbox*1.1)); - b = bigbox * ctx.ctm; + if (b.hasZeroArea()) { // Fallback, spaces mostly + Geom::Rect bigbox(Geom::Point(0.0, -_dsc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, _asc*scale_bigbox*1.1)); + b = bigbox * ctx.ctm; } /* -- cgit v1.2.3 From 19ca801d0d7ac5f1b8e8cb3ef0b872c2cd80e01d Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Wed, 30 Mar 2016 02:08:48 +0200 Subject: Fix for bug #1395435 (Inkscape crashes on load CDR select sheet) and bug #1441437 (crashes when load multi page visio and select page 2 or more) Also clean up code to create dialog a bit and make dialog resizable. Fixed bugs: - https://launchpad.net/bugs/1395435 - https://launchpad.net/bugs/1441437 (bzr r14751) --- src/extension/internal/cdr-input.cpp | 171 ++++++++++++++++---------------- src/extension/internal/vsd-input.cpp | 183 +++++++++++++++++------------------ 2 files changed, 171 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index f4789a08f..a26af2078 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -41,28 +41,18 @@ #endif #include -#include -#include -#include -#include +#include #include "extension/system.h" #include "extension/input.h" -#include "document.h" +#include "document.h" #include "document-private.h" -#include "document-undo.h" #include "inkscape.h" #include "ui/dialog-events.h" -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/frame.h" #include -#include - -#include "svg-view.h" #include "svg-view-widget.h" #include "util/units.h" @@ -82,108 +72,99 @@ public: void getImportSettings(Inkscape::XML::Node *prefs); private: - void _setPreviewPage(unsigned page); + void _setPreviewPage(); // Signal handlers -#if !WITH_GTKMM_3_0 - bool _onExposePreview(GdkEventExpose *event); -#endif - void _onPageNumberChanged(); + void _onSpinButtonPress(GdkEventButton* button_event); + void _onSpinButtonRelease(GdkEventButton* button_event); + class Gtk::VBox * vbox1; + class Gtk::Widget * _previewArea; class Gtk::Button * cancelbutton; class Gtk::Button * okbutton; class Gtk::Label * _labelSelect; - class Inkscape::UI::Widget::SpinButton * _pageNumberSpin; class Gtk::Label * _labelTotalPages; - class Gtk::VBox * vbox1; - class Gtk::VBox * vbox2; - class Gtk::Widget * _previewArea; + class Gtk::SpinButton * _pageNumberSpin; - const std::vector &_vec; // Document to be imported - unsigned _current_page; // Current selected page - int _preview_width, _preview_height; // Size of the preview area + const std::vector &_vec; // Document to be imported + unsigned _current_page; // Current selected page + bool _spinning; // whether SpinButton is pressed (i.e. we're "spinning") }; CdrImportDialog::CdrImportDialog(const std::vector &vec) - : _vec(vec), _current_page(1) + : _vec(vec), _current_page(1), _spinning(false) { int num_pages = _vec.size(); if ( num_pages <= 1 ) return; - cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); - okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); - _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); - // Page number + // Dialog settings + this->set_title(_("Page Selector")); + this->set_modal(true); + sp_transientize(GTK_WIDGET(this->gobj())); //Make transient + this->property_window_position().set_value(Gtk::WIN_POS_NONE); + this->set_resizable(true); + this->property_destroy_with_parent().set_value(false); + + // Preview area + _previewArea = Gtk::manage(new class Gtk::VBox()); + vbox1 = Gtk::manage(new class Gtk::VBox()); + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); #if WITH_GTKMM_3_0 - Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); - _pageNumberSpin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(_pageNumberSpin_adj, 1, 1)); + this->get_content_area()->pack_start(*vbox1); #else - Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage( - new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); - _pageNumberSpin = Gtk::manage(new class Inkscape::UI::Widget::SpinButton(*_pageNumberSpin_adj, 1, 1)); + this->get_vbox()->pack_start(*vbox1); #endif - _labelTotalPages = Gtk::manage(new class Gtk::Label()); - gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); - _labelTotalPages->set_label(label_text); - g_free(label_text); - vbox1 = Gtk::manage(new class Gtk::VBox(false, 4)); - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[0].cstr(), strlen(_vec[0].cstr()), 0); - _previewArea = Glib::wrap(sp_svg_view_widget_new(doc)); - - vbox2 = Gtk::manage(new class Gtk::VBox(false, 4)); - cancelbutton->set_can_focus(); - cancelbutton->set_can_default(); - cancelbutton->set_relief(Gtk::RELIEF_NORMAL); - okbutton->set_can_focus(); - okbutton->set_can_default(); - okbutton->set_relief(Gtk::RELIEF_NORMAL); - this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); + // CONTROLS + + // Buttons + cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); + okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); + + // Labels + _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); + _labelTotalPages = Gtk::manage(new class Gtk::Label()); _labelSelect->set_line_wrap(false); _labelSelect->set_use_markup(false); _labelSelect->set_selectable(false); - _pageNumberSpin->set_can_focus(); - _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); - _pageNumberSpin->set_numeric(true); - _pageNumberSpin->set_digits(0); - _pageNumberSpin->set_wrap(false); _labelTotalPages->set_line_wrap(false); _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); + _labelTotalPages->set_label(label_text); + g_free(label_text); + + // Adjustment + spinner #if WITH_GTKMM_3_0 - this->get_content_area()->set_homogeneous(false); - this->get_content_area()->set_spacing(0); - this->get_content_area()->pack_start(*vbox2); + Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(_pageNumberSpin_adj, 1, 0)); #else - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*vbox2); + Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage(new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(*_pageNumberSpin_adj, 1, 0)); #endif - this->set_title(_("Page Selector")); - this->set_modal(true); - sp_transientize(GTK_WIDGET(this->gobj())); //Make transient - this->property_window_position().set_value(Gtk::WIN_POS_NONE); - this->set_resizable(true); - this->property_destroy_with_parent().set_value(false); + _pageNumberSpin->set_can_focus(); + _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); + _pageNumberSpin->set_numeric(true); + _pageNumberSpin->set_wrap(false); + + this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); this->get_action_area()->add(*_labelSelect); - this->add_action_widget(*_pageNumberSpin, -7); + this->add_action_widget(*_pageNumberSpin, Gtk::RESPONSE_ACCEPT); this->get_action_area()->add(*_labelTotalPages); - this->add_action_widget(*cancelbutton, -6); - this->add_action_widget(*okbutton, -5); - cancelbutton->show(); - okbutton->show(); - _labelSelect->show(); - _pageNumberSpin->show(); - _labelTotalPages->show(); - vbox1->show(); - _previewArea->show(); - vbox2->show(); + this->add_action_widget(*cancelbutton, Gtk::RESPONSE_CANCEL); + this->add_action_widget(*okbutton, Gtk::RESPONSE_OK); + + // Show all widgets in dialog + this->show_all(); // Connect signals - _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &CdrImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_value_changed().connect(sigc::mem_fun(*this, &CdrImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &CdrImportDialog::_onSpinButtonPress)); + _pageNumberSpin->signal_button_release_event().connect_notify(sigc::mem_fun(*this, &CdrImportDialog::_onSpinButtonRelease)); + + _setPreviewPage(); } CdrImportDialog::~CdrImportDialog() {} @@ -193,7 +174,7 @@ bool CdrImportDialog::showDialog() show(); gint b = run(); hide(); - if ( b == Gtk::RESPONSE_OK ) { + if (b == Gtk::RESPONSE_OK || b == Gtk::RESPONSE_ACCEPT) { return TRUE; } else { return FALSE; @@ -209,22 +190,34 @@ void CdrImportDialog::_onPageNumberChanged() { unsigned page = static_cast(_pageNumberSpin->get_value_as_int()); _current_page = CLAMP(page, 1U, _vec.size()); - _setPreviewPage(_current_page); + _setPreviewPage(); +} + +void CdrImportDialog::_onSpinButtonPress(GdkEventButton* /*button_event*/) +{ + _spinning = true; +} + +void CdrImportDialog::_onSpinButtonRelease(GdkEventButton* /*button_event*/) +{ + _spinning = false; + _setPreviewPage(); } /** * \brief Renders the given page's thumbnail */ -void CdrImportDialog::_setPreviewPage(unsigned page) +void CdrImportDialog::_setPreviewPage() { - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[page-1].cstr(), strlen(_vec[page-1].cstr()), 0); + if (_spinning) { + return; + } + + SPDocument *doc = SPDocument::createNewDocFromMem(_vec[_current_page-1].cstr(), strlen(_vec[_current_page-1].cstr()), 0); Gtk::Widget * tmpPreviewArea = Glib::wrap(sp_svg_view_widget_new(doc)); std::swap(_previewArea, tmpPreviewArea); - if (tmpPreviewArea) { - _previewArea->set_size_request( tmpPreviewArea->get_width(), tmpPreviewArea->get_height() ); - delete tmpPreviewArea; - } - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + delete tmpPreviewArea; + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); _previewArea->show_now(); } diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 7fd0d363b..a3d4aad37 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -40,33 +40,24 @@ typedef libvisio::VSDStringVector RVNGStringVector; #endif - #include -#include -#include -#include -#include +#include #include "extension/system.h" #include "extension/input.h" -#include "document.h" +#include "document.h" #include "document-private.h" -#include "document-undo.h" #include "inkscape.h" -#include "util/units.h" #include "ui/dialog-events.h" -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/frame.h" #include -#include - -#include "svg-view.h" #include "svg-view-widget.h" + +#include "util/units.h" + namespace Inkscape { namespace Extension { namespace Internal { @@ -82,108 +73,101 @@ public: void getImportSettings(Inkscape::XML::Node *prefs); private: - void _setPreviewPage(unsigned page); + void _setPreviewPage(); // Signal handlers -#if !WITH_GTKMM_3_0 - bool _onExposePreview(GdkEventExpose *event); -#endif - void _onPageNumberChanged(); + void _onSpinButtonPress(GdkEventButton* button_event); + void _onSpinButtonRelease(GdkEventButton* button_event); + class Gtk::VBox * vbox1; + class Gtk::Widget * _previewArea; class Gtk::Button * cancelbutton; class Gtk::Button * okbutton; class Gtk::Label * _labelSelect; - class Inkscape::UI::Widget::SpinButton * _pageNumberSpin; class Gtk::Label * _labelTotalPages; - class Gtk::VBox * vbox1; - class Gtk::VBox * vbox2; - class Gtk::Widget * _previewArea; + class Gtk::SpinButton * _pageNumberSpin; - const std::vector &_vec; // Document to be imported - unsigned _current_page; // Current selected page - int _preview_width, _preview_height; // Size of the preview area + const std::vector &_vec; // Document to be imported + unsigned _current_page; // Current selected page + bool _spinning; // whether SpinButton is pressed (i.e. we're "spinning") }; VsdImportDialog::VsdImportDialog(const std::vector &vec) - : _vec(vec), _current_page(1) + : _vec(vec), _current_page(1), _spinning(false) { int num_pages = _vec.size(); if ( num_pages <= 1 ) return; - cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); - okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); - _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); - // Page number + + // Dialog settings + this->set_title(_("Page Selector")); + this->set_modal(true); + sp_transientize(GTK_WIDGET(this->gobj())); //Make transient + this->property_window_position().set_value(Gtk::WIN_POS_NONE); + this->set_resizable(true); + this->property_destroy_with_parent().set_value(false); + + // Preview area + _previewArea = Gtk::manage(new class Gtk::VBox()); + vbox1 = Gtk::manage(new class Gtk::VBox()); + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); #if WITH_GTKMM_3_0 - Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); - _pageNumberSpin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(_pageNumberSpin_adj, 1, 1)); + this->get_content_area()->pack_start(*vbox1); #else - Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage( - new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); - _pageNumberSpin = Gtk::manage(new class Inkscape::UI::Widget::SpinButton(*_pageNumberSpin_adj, 1, 1)); + this->get_vbox()->pack_start(*vbox1); #endif - _labelTotalPages = Gtk::manage(new class Gtk::Label()); - gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); - _labelTotalPages->set_label(label_text); - g_free(label_text); - vbox1 = Gtk::manage(new class Gtk::VBox(false, 4)); - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[0].cstr(), strlen(_vec[0].cstr()), 0); - _previewArea = Glib::wrap(sp_svg_view_widget_new(doc)); - - vbox2 = Gtk::manage(new class Gtk::VBox(false, 4)); - cancelbutton->set_can_focus(); - cancelbutton->set_can_default(); - cancelbutton->set_relief(Gtk::RELIEF_NORMAL); - okbutton->set_can_focus(); - okbutton->set_can_default(); - okbutton->set_relief(Gtk::RELIEF_NORMAL); - this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); + + // CONTROLS + + // Buttons + cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); + okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); + + // Labels + _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); + _labelTotalPages = Gtk::manage(new class Gtk::Label()); _labelSelect->set_line_wrap(false); _labelSelect->set_use_markup(false); _labelSelect->set_selectable(false); - _pageNumberSpin->set_can_focus(); - _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); - _pageNumberSpin->set_numeric(true); - _pageNumberSpin->set_digits(0); - _pageNumberSpin->set_wrap(false); _labelTotalPages->set_line_wrap(false); _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); + _labelTotalPages->set_label(label_text); + g_free(label_text); + + // Adjustment + spinner #if WITH_GTKMM_3_0 - this->get_content_area()->set_homogeneous(false); - this->get_content_area()->set_spacing(0); - this->get_content_area()->pack_start(*vbox2); + Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(_pageNumberSpin_adj, 1, 0)); #else - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*vbox2); + Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage(new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(*_pageNumberSpin_adj, 1, 0)); #endif - this->set_title(_("Page Selector")); - this->set_modal(true); - sp_transientize(GTK_WIDGET(this->gobj())); //Make transient - this->property_window_position().set_value(Gtk::WIN_POS_NONE); - this->set_resizable(true); - this->property_destroy_with_parent().set_value(false); + _pageNumberSpin->set_can_focus(); + _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); + _pageNumberSpin->set_numeric(true); + _pageNumberSpin->set_wrap(false); + + this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); this->get_action_area()->add(*_labelSelect); - this->add_action_widget(*_pageNumberSpin, -7); + this->add_action_widget(*_pageNumberSpin, Gtk::RESPONSE_ACCEPT); this->get_action_area()->add(*_labelTotalPages); - this->add_action_widget(*cancelbutton, -6); - this->add_action_widget(*okbutton, -5); - cancelbutton->show(); - okbutton->show(); - _labelSelect->show(); - _pageNumberSpin->show(); - _labelTotalPages->show(); - vbox1->show(); - _previewArea->show(); - vbox2->show(); + this->add_action_widget(*cancelbutton, Gtk::RESPONSE_CANCEL); + this->add_action_widget(*okbutton, Gtk::RESPONSE_OK); + + // Show all widgets in dialog + this->show_all(); // Connect signals - _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &VsdImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_value_changed().connect(sigc::mem_fun(*this, &VsdImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &VsdImportDialog::_onSpinButtonPress)); + _pageNumberSpin->signal_button_release_event().connect_notify(sigc::mem_fun(*this, &VsdImportDialog::_onSpinButtonRelease)); + + _setPreviewPage(); } VsdImportDialog::~VsdImportDialog() {} @@ -193,7 +177,7 @@ bool VsdImportDialog::showDialog() show(); gint b = run(); hide(); - if ( b == Gtk::RESPONSE_OK ) { + if (b == Gtk::RESPONSE_OK || b == Gtk::RESPONSE_ACCEPT) { return TRUE; } else { return FALSE; @@ -209,22 +193,34 @@ void VsdImportDialog::_onPageNumberChanged() { unsigned page = static_cast(_pageNumberSpin->get_value_as_int()); _current_page = CLAMP(page, 1U, _vec.size()); - _setPreviewPage(_current_page); + _setPreviewPage(); +} + +void VsdImportDialog::_onSpinButtonPress(GdkEventButton* /*button_event*/) +{ + _spinning = true; +} + +void VsdImportDialog::_onSpinButtonRelease(GdkEventButton* /*button_event*/) +{ + _spinning = false; + _setPreviewPage(); } /** * \brief Renders the given page's thumbnail */ -void VsdImportDialog::_setPreviewPage(unsigned page) +void VsdImportDialog::_setPreviewPage() { - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[page-1].cstr(), strlen(_vec[page-1].cstr()), 0); + if (_spinning) { + return; + } + + SPDocument *doc = SPDocument::createNewDocFromMem(_vec[_current_page-1].cstr(), strlen(_vec[_current_page-1].cstr()), 0); Gtk::Widget * tmpPreviewArea = Glib::wrap(sp_svg_view_widget_new(doc)); std::swap(_previewArea, tmpPreviewArea); - if (tmpPreviewArea) { - _previewArea->set_size_request( tmpPreviewArea->get_width(), tmpPreviewArea->get_height() ); - delete tmpPreviewArea; - } - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + delete tmpPreviewArea; + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); _previewArea->show_now(); } @@ -282,12 +278,11 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u } SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); - + // Set viewBox if it doesn't exist - if (!doc->getRoot()->viewBox_set) { + if (doc && !doc->getRoot()->viewBox_set) { doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } - return doc; } -- cgit v1.2.3 From a18efaedfcc01ec5bd1b9c60ca55b8be4445c5cb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Mar 2016 19:26:19 +0200 Subject: Partial fix for bug 156221 ('line-height' with non-pixel scaled drawing). (bzr r14752) --- src/desktop-style.cpp | 14 ++++++++++---- src/sp-text.cpp | 7 +++++++ src/widgets/text-toolbar.cpp | 10 ++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 5f6441aa7..7f9b46c7d 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1073,7 +1073,12 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r texts ++; SPItem *item = dynamic_cast(obj); g_assert(item != NULL); - double dummy = style->font_size.computed * Geom::Affine(item->i2dt_affine()).descrim(); + + // Quick way of getting document scale. Should be same as: + // item->document->getDocumentScale().Affine().descrim() + double doc_scale = Geom::Affine(item->i2dt_affine()).descrim(); + + double dummy = style->font_size.computed * doc_scale; if (!IS_NAN(dummy)) { size += dummy; /// \todo FIXME: we assume non-% units here } else { @@ -1085,7 +1090,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r letterspacing_normal = true; } } else { - letterspacing += style->letter_spacing.computed * Geom::Affine(item->i2dt_affine()).descrim(); /// \todo FIXME: we assume non-% units here + letterspacing += style->letter_spacing.computed * doc_scale;; /// \todo FIXME: we assume non-% units here letterspacing_normal = false; } @@ -1094,7 +1099,7 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r wordspacing_normal = true; } } else { - wordspacing += style->word_spacing.computed * Geom::Affine(item->i2dt_affine()).descrim(); /// \todo FIXME: we assume non-% units here + wordspacing += style->word_spacing.computed * doc_scale; /// \todo FIXME: we assume non-% units here wordspacing_normal = false; } @@ -1119,14 +1124,15 @@ objects_query_fontnumbers (const std::vector &objects, SPStyle *style_r lineheight_unit_current = style->line_height.unit; lineheight_unit_proportional = true; lineheight_normal = false; + lineheight += lineheight_current; } else { // Always 'px' internally lineheight_current = style->line_height.computed; lineheight_unit_current = style->line_height.unit; lineheight_unit_absolute = true; lineheight_normal = false; + lineheight += lineheight_current * doc_scale; } - lineheight += lineheight_current; if ((size_prev != 0 && style->font_size.computed != size_prev) || (letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) || diff --git a/src/sp-text.cpp b/src/sp-text.cpp index da92ad8d4..6ae1c4fba 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -645,6 +645,13 @@ void SPText::_adjustFontsizeRecursive(SPItem *item, double ex, bool is_root) style->font_size.computed *= ex; style->letter_spacing.computed *= ex; style->word_spacing.computed *= ex; + if (style->line_height.unit != SP_CSS_UNIT_NONE && + style->line_height.unit != SP_CSS_UNIT_PERCENT && + style->line_height.unit != SP_CSS_UNIT_EM && + style->line_height.unit != SP_CSS_UNIT_EX) { + // No unit on 'line-height' property has special behavior. + style->line_height.computed *= ex; + } item->updateRepr(); } diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 8df80d2b6..e71c911bd 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -638,7 +638,8 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) int count = 0; for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { - font_size += (*i)->style->font_size.computed; + double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); + font_size += (*i)->style->font_size.computed * doc_scale; ++count; } } @@ -662,7 +663,8 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) int count = 0; for(std::vector::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { - font_size += (*i)->style->font_size.computed; + double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); + font_size += (*i)->style->font_size.computed * doc_scale; ++count; } } @@ -671,12 +673,13 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) } else { font_size = 20; } - line_height *= font_size; + if (old_unit == SP_CSS_UNIT_PERCENT) { line_height /= 100.0; } else if (old_unit == SP_CSS_UNIT_EX) { line_height /= 2.0; } + line_height *= font_size; line_height = Quantity::convert(line_height, "px", unit); } else { // Convert between different absolute units (only used in GUI) @@ -1252,7 +1255,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ double height; int line_height_unit = -1; if (query.line_height.normal) { - std::cout << " normal" << std::endl; height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; line_height_unit = SP_CSS_UNIT_NONE; } else { -- cgit v1.2.3 From fd1988584d74008516463f33fc98e819ab838f9b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Mar 2016 20:58:46 +0200 Subject: Finish fixing bug 156221 ('line-height' with non-px scaling). (bzr r14753) --- src/style.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index 1f98a50a3..c24818f2a 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1900,8 +1900,9 @@ sp_css_attr_scale_property_single(SPCSSAttr *css, gchar const *property, if (w == units) {// nothing converted, non-numeric value return; } - if (only_with_units && (units == NULL || *units == '\0' || *units == '%')) { + if (only_with_units && (units == NULL || *units == '\0' || *units == '%' || *units == 'e')) { // only_with_units, but no units found, so do nothing. + // 'e' matches 'em' or 'ex' return; } Inkscape::CSSOStringStream os; -- cgit v1.2.3 From a6b3ec9cdaf7867d6b02da3122ab4c06bf2246a5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 1 Apr 2016 09:35:30 -0400 Subject: Fix regression in swatch color selection and improve it by allowing drag to change the swatch color too. Fixed bugs: - https://launchpad.net/bugs/1564597 (bzr r14757) --- src/widgets/swatch-selector.cpp | 48 +++++------------------------------------ 1 file changed, 5 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp index 6f2807255..b9cce1d19 100644 --- a/src/widgets/swatch-selector.cpp +++ b/src/widgets/swatch-selector.cpp @@ -37,10 +37,11 @@ SwatchSelector::SwatchSelector() : color_selector->show(); pack_start(*color_selector); - _selected_color.signal_grabbed.connect(sigc::mem_fun(this, &SwatchSelector::_grabbedCb)); - _selected_color.signal_dragged.connect(sigc::mem_fun(this, &SwatchSelector::_draggedCb)); - _selected_color.signal_released.connect(sigc::mem_fun(this, &SwatchSelector::_releasedCb)); - _selected_color.signal_changed.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb)); + //_selected_color.signal_grabbed.connect(sigc::mem_fun(this, &SwatchSelector::_grabbedCb)); + _selected_color.signal_dragged.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb)); + _selected_color.signal_released.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb)); + // signal_changed doesn't get called if updating shape with colour. + //_selected_color.signal_changed.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb)); } SwatchSelector::~SwatchSelector() @@ -53,45 +54,6 @@ SPGradientSelector *SwatchSelector::getGradientSelector() return _gsel; } -void SwatchSelector::_grabbedCb() -{ -} - -void SwatchSelector::_draggedCb() -{ - // if (data) { - //SwatchSelector *swsel = reinterpret_cast(data); - - // TODO might have to block cycles - - // Copied from gradient-vector.cpp, but does not appear to cause visible changes: - /* - if (swsel->_gsel) { - SPGradient *gradient = swsel->_gsel->getVector(); - SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient); - if (ngr != gradient) { - // Our master gradient has changed - // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr); - } - - sp_gradient_ensure_vector(ngr); - - - SPStop* stop = ngr->getFirstStop(); - if (stop) { - swsel->_csel->base->getColorAlpha(stop->specified_color, &stop->opacity); - stop->currentColor = false; - // TODO push refresh - } - } - */ - // } -} - -void SwatchSelector::_releasedCb() -{ -} - void SwatchSelector::_changedCb() { if (_updating_color) { -- cgit v1.2.3 From 517ad6d0a849329510ea7927742687c28b97c54e Mon Sep 17 00:00:00 2001 From: insaner and su_v <> Date: Sat, 2 Apr 2016 11:10:37 +0200 Subject: Add icon for Live Path Effects dialog. (bzr r14758) --- src/verbs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index a78bde2f7..b665d6c27 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2949,7 +2949,7 @@ Verb *Verb::_base_verbs[] = { new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogTags", N_("Selection se_ts..."), N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")), new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), - N_("Manage, edit, and apply path effects"), NULL), + N_("Manage, edit, and apply path effects"), INKSCAPE_ICON("dialog-path-effects")), new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), N_("Manage, edit, and apply SVG filters"), INKSCAPE_ICON("dialog-filters")), new DialogVerb(SP_VERB_DIALOG_SVG_FONTS, "DialogSVGFonts", N_("SVG Font Editor..."), -- cgit v1.2.3 From 8199cf68c6dbb74a7f1b4eedb970427171bb4d9f Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 2 Apr 2016 17:15:43 +0200 Subject: Fix crash on copying orphaned clones Fixed bugs: - https://launchpad.net/bugs/1565272 (bzr r14759) --- src/ui/clipboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index f04d8a591..f0dc33740 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -759,7 +759,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) { SPUse *use=dynamic_cast(item); - if(use){ + if (use && use->get_original()) { if(cloned_elements.insert(use->get_original()).second) _copyUsedDefs(use->get_original()); } -- cgit v1.2.3 From ba034a786957d33d5bc554d337208f68e4c1976e Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 2 Apr 2016 12:53:34 -0400 Subject: Remove unused variable warnings. (bzr r14760) --- src/verbs.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index b665d6c27..7b128c172 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -952,10 +952,6 @@ void EditVerb::perform(SPAction *action, void *data) g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = dt->getDocument(); - - Inkscape::XML::Node *repr = dt->namedview->getRepr(); - switch (reinterpret_cast(data)) { case SP_VERB_EDIT_UNDO: sp_undo(dt, dt->getDocument()); -- cgit v1.2.3 From ab843636c11bb0d0550a8987fbdfcb089a55832e Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 2 Apr 2016 14:21:12 -0400 Subject: Fix node size regression and add ctrlResize property for multiple use. Fixed bugs: - https://launchpad.net/bugs/1562197 (bzr r14761) --- src/display/sp-canvas-item.h | 1 + src/display/sp-canvas.cpp | 1 + src/ui/control-manager.cpp | 56 +++++++++++++++++++++++++++----------------- src/ui/control-manager.h | 2 ++ src/ui/draw-anchor.cpp | 12 ++++------ 5 files changed, 43 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index 66cd03dd9..00edb4dee 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -62,6 +62,7 @@ struct SPCanvasItem { Geom::Rect bounds; Geom::Affine xform; + int ctrlResize; Inkscape::ControlType ctrlType; Inkscape::ControlFlags ctrlFlags; diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index d17271752..81ea7d142 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -360,6 +360,7 @@ static void sp_canvas_item_init(SPCanvasItem *item) { item->xform = Geom::Affine(Geom::identity()); + item->ctrlResize = 0; item->ctrlType = Inkscape::CTRL_TYPE_UNKNOWN; item->ctrlFlags = Inkscape::CTRL_FLAG_NORMAL; diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index cedaea405..a2c977533 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -54,9 +54,6 @@ ControlFlags& operator ^=(ControlFlags &lhs, ControlFlags rhs) } // namespace -#define FILL_COLOR_NORMAL 0xffffff7f -#define FILL_COLOR_MOUSEOVER 0xff0000ff - // Default color for line: #define LINE_COLOR_PRIMARY 0x0000ff7f #define LINE_COLOR_SECONDARY 0xff00007f @@ -83,6 +80,8 @@ public: bool setControlType(SPCanvasItem *item, ControlType type); + bool setControlResize(SPCanvasItem *item, int ctrlResize); + void setSelected(SPCanvasItem *item, bool selected); private: @@ -108,12 +107,13 @@ private: ControlManager &_manager; sigc::signal _sizeChangedSignal; PrefListener _prefHook; - int _size; + int _size; // Size from the grabsize preference + int _resize; // Way size should change from grabsize std::vector _itemList; std::map > _sizeTable; std::map _typeTable; std::map _ctrlToShape; - std::set _sizeChangers; + std::set _resizeOnSelect; }; ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : @@ -121,6 +121,7 @@ ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : _sizeChangedSignal(), _prefHook(*this), _size(3), + _resize(3), _itemList(), _sizeTable() { @@ -153,10 +154,10 @@ ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : // ------- - _sizeChangers.insert(CTRL_TYPE_NODE_AUTO); - _sizeChangers.insert(CTRL_TYPE_NODE_CUSP); - _sizeChangers.insert(CTRL_TYPE_NODE_SMOOTH); - _sizeChangers.insert(CTRL_TYPE_NODE_SYMETRICAL); + _resizeOnSelect.insert(CTRL_TYPE_NODE_AUTO); + _resizeOnSelect.insert(CTRL_TYPE_NODE_CUSP); + _resizeOnSelect.insert(CTRL_TYPE_NODE_SMOOTH); + _resizeOnSelect.insert(CTRL_TYPE_NODE_SYMETRICAL); // ------- @@ -234,7 +235,7 @@ SPCanvasItem *ControlManagerImpl::createControl(SPCanvasGroup *parent, ControlTy item = sp_canvas_item_new(parent, SP_TYPE_CTRL, "size", targetSize, "filled", 1, - "fill_color", FILL_COLOR_NORMAL, + "fill_color", 0xffffff7f, "stroked", 1, "stroke_color", 0x000000ff, NULL); @@ -284,11 +285,8 @@ sigc::connection ControlManagerImpl::connectCtrlSizeChanged(const sigc::slotctrlType][_size - 1]; + double target = _sizeTable[item->ctrlType][_size - 1] + item->ctrlResize; - if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { - target += 2; - } g_object_set(item, "size", target, NULL); sp_canvas_item_request_update(item); @@ -303,11 +301,9 @@ bool ControlManagerImpl::setControlType(SPCanvasItem *item, ControlType type) accepted = true; } else if (item) { if (_ctrlToShape.count(type) && (_typeTable[type] == _typeTable[item->ctrlType])) { // compatible? - double targetSize = _sizeTable[type][_size - 1]; - if (_manager.isSelected(item) && _sizeChangers.count(item->ctrlType)) { - targetSize += 2.0; - } + double targetSize = _sizeTable[type][_size - 1] + item->ctrlResize; SPCtrlShapeType targetShape = _ctrlToShape[type]; + g_object_set(item, "shape", targetShape, "size", targetSize, NULL); item->ctrlType = type; accepted = true; @@ -317,17 +313,28 @@ bool ControlManagerImpl::setControlType(SPCanvasItem *item, ControlType type) return accepted; } +bool ControlManagerImpl::setControlResize(SPCanvasItem *item, int ctrlResize) +{ + if(item) { + item->ctrlResize = ctrlResize; + double targetSize = _sizeTable[item->ctrlType][_size - 1] + item->ctrlResize; + g_object_set(item, "size", targetSize, NULL); + return true; + } + return false; +} void ControlManagerImpl::setSelected(SPCanvasItem *item, bool selected) { if (_manager.isSelected(item) != selected) { item->ctrlFlags ^= CTRL_FLAG_SELECTED; // toggle, since we know it is different - // TODO refresh colors - double targetSize = _sizeTable[item->ctrlType][_size - 1]; - if (selected && _sizeChangers.count(item->ctrlType)) { - targetSize += 2.0; + if (selected && _resizeOnSelect.count(item->ctrlType)) { + item->ctrlResize = 2; } + + // TODO refresh colors + double targetSize = _sizeTable[item->ctrlType][_size - 1] + _resize; g_object_set(item, "size", targetSize, NULL); } } @@ -431,6 +438,11 @@ bool ControlManager::setControlType(SPCanvasItem *item, ControlType type) return _impl->setControlType(item, type); } +bool ControlManager::setControlResize(SPCanvasItem *item, int ctrlResize) +{ + return _impl->setControlResize(item, ctrlResize); +} + bool ControlManager::isActive(SPCanvasItem *item) const { return (item->ctrlFlags & CTRL_FLAG_ACTIVE) != 0; diff --git a/src/ui/control-manager.h b/src/ui/control-manager.h index 964ad0a29..3f090d0bd 100644 --- a/src/ui/control-manager.h +++ b/src/ui/control-manager.h @@ -63,6 +63,8 @@ public: bool setControlType(SPCanvasItem *item, ControlType type); + bool setControlResize(SPCanvasItem *item, int ctrlResize); + bool isActive(SPCanvasItem *item) const; void setActive(SPCanvasItem *item, bool active); diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp index e5a7a493e..c3bc5676d 100644 --- a/src/ui/draw-anchor.cpp +++ b/src/ui/draw-anchor.cpp @@ -26,9 +26,6 @@ using Inkscape::ControlManager; #define FILL_COLOR_NORMAL 0xffffff7f #define FILL_COLOR_MOUSEOVER 0xff0000ff -#define NODE_SIZE_NORMAL 7.0 -#define NODE_SIZE_MOUSEOVER 10.0 - /** * Creates an anchor object and initializes it. */ @@ -81,18 +78,19 @@ SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool acti if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) { if (!anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, - "size", NODE_SIZE_MOUSEOVER, NULL); + ControlManager::getManager().setControlResize(anchor->ctrl, 4); + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL); anchor->active = TRUE; } return anchor; } if (anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, - "size", NODE_SIZE_NORMAL, NULL); + ControlManager::getManager().setControlResize(anchor->ctrl, 0); + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL); anchor->active = FALSE; } + return NULL; } -- cgit v1.2.3 From 3ae9b262529ea9e276a1acc2f7ebdb393079c514 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Mon, 4 Apr 2016 19:05:14 -0400 Subject: avoid higher-order calculations if sbasis is cubic. (Bug 1559721) Fixed bugs: - https://launchpad.net/bugs/1559721 (bzr r14762) --- src/2geom/sbasis-to-bezier.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index 8a18cfd4a..64c07f35e 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -197,6 +197,8 @@ void sbasis_to_cubic_bezier (std::vector & bz, D2 const& sb) } sbasis_to_bezier(bz, sb, 4); // zeroth-order estimate + if ((sb[X].size() < 3) && (sb[Y].size() < 3)) + return; // cubic bezier estimate is exact Geom::ConvexHull bezhull(bz); // calculate first derivatives of x and y wrt t -- cgit v1.2.3 From c2c0e21ac5ed06791b74905272039276d99685a1 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Tue, 5 Apr 2016 11:13:27 -0400 Subject: re-write rev 11457. (Bug 1557348) Fixed bugs: - https://launchpad.net/bugs/1557348 (bzr r14763) --- src/livarot/PathOutline.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp index e146bb908..1c42301da 100644 --- a/src/livarot/PathOutline.cpp +++ b/src/livarot/PathOutline.cpp @@ -471,8 +471,13 @@ void Path::SubContractOutline(int off, int num_pd, // test de nullité du segment if (IsNulCurve (descr_cmd, curD, curX)) { - stTgt = dest->descr_cmd.size() ? Geom::Point(1, 0) : Geom::Point(-1, 0); // reverse direction - enTgt = stTgt; + if (descr_cmd.size() == 2) { // single point, see LP Bug 1006666 + stTgt = dest->descr_cmd.size() ? Geom::Point(1, 0) : Geom::Point(-1, 0); // reverse direction + enTgt = stTgt; + } else { + curP++; + continue; + } } stNor=stTgt.cw(); enNor=enTgt.cw(); -- cgit v1.2.3 From d3460d8a60c4d2c99c2c12fe0646db224335e232 Mon Sep 17 00:00:00 2001 From: Kamalpreet Grewal <> Date: Thu, 7 Apr 2016 12:54:08 +0200 Subject: Add clickable link to www.inkscape.org to splash screen dialog. (bzr r14764) --- src/ui/dialog/aboutbox.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 81f48e6ef..b653a630d 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -120,10 +120,22 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) { label->set_selectable(true); label->show(); + Gtk::Label *link = new Gtk::Label(); + const gchar *website_link = + " https://www.inkscape.org"; + + link->set_markup(website_link); + link->set_alignment(Gtk::ALIGN_END); + link->set_padding(5,5); + link->set_selectable(true); + link->show(); + #if WITH_GTKMM_3_0 get_content_area()->pack_start(*manage(label), false, false); + get_content_area()->pack_start(*manage(link), false, false); #else get_vbox()->pack_start(*manage(label), false, false); + get_vbox()->pack_start(*manage(link), false, false); #endif Gtk::Requisition requisition; -- cgit v1.2.3 From 03e7b13ab09c39d2147e06138c517f0199d4f091 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 8 Apr 2016 15:26:55 +0200 Subject: Bug #1552765 fixed Break Apart dont handle well stroke with in documents different than px Fixed bugs: - https://launchpad.net/bugs/1552765 (bzr r14765) --- src/path-chemistry.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 15d3f0f99..1a345b565 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -1,4 +1,4 @@ -/* + /* * Here are handlers for modifying selections, specific to paths * * Authors: @@ -217,7 +217,6 @@ sp_selected_path_break_apart(SPDesktop *desktop, bool skip_undo) if (curve == NULL) { continue; } - did = true; Inkscape::XML::Node *parent = item->getRepr()->parent(); @@ -228,16 +227,10 @@ sp_selected_path_break_apart(SPDesktop *desktop, bool skip_undo) gchar *style = g_strdup(item->getRepr()->attribute("style")); // XML Tree being used directly here while it shouldn't be... gchar *path_effect = g_strdup(item->getRepr()->attribute("inkscape:path-effect")); - - Geom::PathVector apv = curve->get_pathvector() * path->transform; - - curve->unref(); - + Geom::Affine transform = path->transform; // it's going to resurrect as one of the pieces, so we delete without advertisement item->deleteObject(false); - curve = new SPCurve(apv); - g_assert(curve != NULL); GSList *list = curve->split(); @@ -258,7 +251,8 @@ sp_selected_path_break_apart(SPDesktop *desktop, bool skip_undo) else repr->setAttribute("d", str); g_free(str); - + repr->setAttribute("transform", sp_svg_transform_write(transform)); + // add the new repr to the parent parent->appendChild(repr); -- cgit v1.2.3