From: dvlierop2 Date: Sat, 12 Jan 2008 20:55:16 +0000 (+0000) Subject: Fix #181795 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=eb55bb43a2868b909d1f2ad0489a5c71683127f9;p=inkscape.git Fix #181795 --- diff --git a/src/seltrans.cpp b/src/seltrans.cpp index a747e6b4a..f7ffe69c0 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -919,9 +919,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) s, _origin_for_specpoints); - if (bb.second == false && sn.second == false) { - /* We didn't snap, so just keep the locked aspect ratio */ - } else { + if (bb.second || sn.second) { // If we snapped to something /* Choose the smaller difference in scale. Since s[X] == s[Y] we can ** just compare difference in s[X]. */ @@ -944,16 +942,18 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) s, _origin_for_specpoints); - /* Pick the snap that puts us closest to the original scale */ - NR::Coord bd = bb.second ? - fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) - - NR::L2(NR::Point(s[NR::X], s[NR::Y]))) - : NR_HUGE; - NR::Coord sd = sn.second ? - fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) - - NR::L2(NR::Point(s[NR::X], s[NR::Y]))) - : NR_HUGE; - s = (bd < sd) ? bb.first : sn.first; + if (bb.second || sn.second) { // If we snapped to something + /* Pick the snap that puts us closest to the original scale */ + NR::Coord bd = bb.second ? + fabs(NR::L2(NR::Point(bb.first[NR::X], bb.first[NR::Y])) - + NR::L2(NR::Point(s[NR::X], s[NR::Y]))) + : NR_HUGE; + NR::Coord sd = sn.second ? + fabs(NR::L2(NR::Point(sn.first[NR::X], sn.first[NR::Y])) - + NR::L2(NR::Point(s[NR::X], s[NR::Y]))) + : NR_HUGE; + s = (bd < sd) ? bb.first : sn.first; + } } /* Update the knot position */ @@ -1022,7 +1022,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: // on ctrl, apply symmetrical scaling instead of stretching s[perp] = fabs(s[axis]); - std::pair const bb = m.freeSnapStretch( + std::pair const bb = m.constrainedSnapStretch( Snapper::SNAPPOINT_BBOX, _bbox_points, it, @@ -1031,7 +1031,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: axis, true); - std::pair const sn = m.freeSnapStretch( + std::pair const sn = m.constrainedSnapStretch( Snapper::SNAPPOINT_NODE, _snap_points, it, @@ -1040,15 +1040,20 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: axis, true); - NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; - NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; - NR::Coord const ratio = (bd < sd) ? bb.first : sn.first; - - s[axis] = fabs(ratio) * sign(s[axis]); - s[perp] = fabs(s[axis]); + if (bb.second || sn.second) { // If we snapped to something + /* Choose the smaller difference in scale */ + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + NR::Coord const ratio = (bd < sd) ? bb.first : sn.first; + + if (fabs(ratio) < NR_HUGE) { + s[axis] = fabs(ratio) * sign(s[axis]); + } + s[perp] = fabs(s[axis]); + } } else { - std::pair const bb = m.freeSnapStretch( + std::pair const bb = m.constrainedSnapStretch( Snapper::SNAPPOINT_BBOX, _bbox_points, it, @@ -1057,7 +1062,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: axis, false); - std::pair const sn = m.freeSnapStretch( + std::pair const sn = m.constrainedSnapStretch( Snapper::SNAPPOINT_NODE, _snap_points, it, @@ -1066,12 +1071,16 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: axis, false); - /* Choose the smaller difference in scale */ - NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; - NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; - s[axis] = (bd < sd) ? bb.first : sn.first; - - s[perp] = 1; + if (bb.second || sn.second) { // If we snapped to something + /* Choose the smaller difference in scale */ + NR::Coord const bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord const sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + NR::Coord const nw = (bd < sd) ? bb.first : sn.first; // new stretch scale + if (fabs(nw) < NR_HUGE) { + s[axis] = nw; + } + s[perp] = 1; + } } pt = ( _point - _origin ) * NR::scale(s) + _origin; diff --git a/src/snap.cpp b/src/snap.cpp index 73a3b010b..cb4ea3f58 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -393,7 +393,7 @@ std::pair SnapManager::_snapTransformed( std::vector::const_iterator j = transformed_points.begin(); //std::cout << std::endl; - + for (std::vector::const_iterator i = points.begin(); i != points.end(); i++) { /* Snap it */ @@ -401,11 +401,13 @@ std::pair SnapManager::_snapTransformed( if (constrained) { Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint; - if (transformation_type == SCALE && uniform) { + if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) { // When uniformly scaling, each point will have its own unique constraint line, // running from the scaling origin to the original untransformed point. We will // calculate that line here dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, (*i) - origin); + } else if (transformation_type == STRETCH || transformation_type == SKEW) { // when skewing or non-uniform stretching { + dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]); } // else: leave the original constraint, e.g. for constrained translation if (transformation_type == SCALE && !uniform) { g_warning("Non-uniform constrained scaling is not supported!"); @@ -424,6 +426,9 @@ std::pair SnapManager::_snapTransformed( /* We snapped. Find the transformation that describes where the snapped point has ** ended up, and also the metric for this transformation. */ + NR::Point const a = (snapped.getPoint() - origin); // vector to snapped point + NR::Point const b = (*i - origin); // vector to original point + switch (transformation_type) { case TRANSLATION: result = snapped.getPoint() - *i; @@ -441,8 +446,6 @@ std::pair SnapManager::_snapTransformed( break; case SCALE: { - NR::Point const a = (snapped.getPoint() - origin); // vector to snapped point - NR::Point const b = (*i - origin); // vector to original point result = NR::Point(NR_HUGE, NR_HUGE); // If this point *i is horizontally or vertically aligned with // the origin of the scaling, then it will scale purely in X or Y @@ -458,17 +461,19 @@ std::pair SnapManager::_snapTransformed( // if scaling didn't occur in the other direction } } - // Compare the resulting scaling with the desired scaling scale_metric = result - transformation; // One or both of its components might be NR_HUGE break; } case STRETCH: - for (int index = 0; index < 2; index++) { - if (uniform || index == dim) { - result[index] = (snapped.getPoint()[dim] - origin[dim]) / ((*i)[dim] - origin[dim]); - } else { - result[index] = 1; + result = NR::Point(NR_HUGE, NR_HUGE); + if (fabs(b[dim]) > 1e-6) { // if STRETCHING will occur for this point + result[dim] = a[dim] / b[dim]; + result[1-dim] = uniform ? result[dim] : 1; + } else { // STRETCHING might occur for this point, but only when the stretching is uniform + if (uniform && fabs(b[1-dim]) > 1e-6) { + result[1-dim] = a[1-dim] / b[1-dim]; + result[dim] = result[1-dim]; } } metric = std::abs(result[dim] - transformation[dim]); @@ -521,7 +526,6 @@ std::pair SnapManager::_snapTransformed( } } - j++; } @@ -655,7 +659,7 @@ std::pair SnapManager::constrainedSnapScale(Inkscape::Snapper:: * \return Snapped stretch, if a snap occurred, and a flag indicating whether a snap occurred. */ -std::pair SnapManager::freeSnapStretch(Inkscape::Snapper::PointType t, +std::pair SnapManager::constrainedSnapStretch(Inkscape::Snapper::PointType t, std::vector const &p, std::list const &it, NR::Coord const &s, @@ -664,7 +668,7 @@ std::pair SnapManager::freeSnapStretch(Inkscape::Snapper::Point bool u) const { std::pair const r = _snapTransformed( - t, p, it, false, NR::Point(), STRETCH, NR::Point(s, s), o, d, u + t, p, it, true, NR::Point(), STRETCH, NR::Point(s, s), o, d, u ); return std::make_pair(r.first[d], r.second); @@ -700,23 +704,8 @@ std::pair SnapManager::freeSnapSkew(Inkscape::Snapper::PointTyp Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedConstraints &sc, bool constrained) const { - NR::Coord const guide_tol = guide.getSnapperTolerance(); - NR::Coord grid_tol = 0; - - SnapManager::SnapperList const gs = getGridSnappers(); - SnapperList::const_iterator i = gs.begin(); - if (i != gs.end()) { - grid_tol = (*i)->getSnapperTolerance(); // there's only a single tolerance, equal for all grids - } - // Store all snappoints std::list sp_list; - // Most of these snapped points are already within the snapping range, because - // they have already been filtered by their respective snappers. In that case - // we can set the snapping range to NR_HUGE here. If however we're looking at - // intersections of e.g. a grid and guide line, then we'll have to determine - // once again whether we're within snapping range. In this case we will set - // the snapping range to e.g. min(guide_sens, grid_tol) // search for the closest snapped point Inkscape::SnappedPoint closestPoint; diff --git a/src/snap.h b/src/snap.h index ee9dbefac..9702d011a 100644 --- a/src/snap.h +++ b/src/snap.h @@ -94,7 +94,7 @@ public: NR::scale const &s, NR::Point const &o) const; - std::pair freeSnapStretch(Inkscape::Snapper::PointType t, + std::pair constrainedSnapStretch(Inkscape::Snapper::PointType t, std::vector const &p, std::list const &it, NR::Coord const &s,