summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d23d8bd)
raw | patch | inline | side by side (parent: d23d8bd)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Wed, 10 Dec 2008 21:51:33 +0000 (21:51 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Wed, 10 Dec 2008 21:51:33 +0000 (21:51 +0000) |
- Replace tabs by spaces
src/snap.cpp | patch | blob | history | |
src/snapped-curve.cpp | patch | blob | history | |
src/snapped-line.cpp | patch | blob | history | |
src/snapped-point.cpp | patch | blob | history |
diff --git a/src/snap.cpp b/src/snap.cpp
index e13809256660fe942c33e9484dbc49c91c12a46e..ac2f1321cdc3293ef14a3450a7e436e535ece7a8 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
guide(this, 0),
object(this, 0),
snapprefs(),
- _named_view(v)
-{
+ _named_view(v)
+{
}
/**
* \return List of snappers that we use.
*/
-SnapManager::SnapperList
+SnapManager::SnapperList
SnapManager::getSnappers() const
{
SnapManager::SnapperList s;
/**
* \return List of gridsnappers that we use.
*/
-SnapManager::SnapperList
+SnapManager::SnapperList
SnapManager::getGridSnappers() const
{
SnapperList s;
if ( !snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally() ) {
return false;
}
-
+
SnapperList const s = getSnappers();
SnapperList::const_iterator i = s.begin();
while (i != s.end() && (*i)->ThisSnapperMightSnap() == false) {
i++;
}
-
+
return (i != s.end());
}
*
* \param point_type Type of point.
* \param p Point.
- * \param first_point If true then this point is the first one from a whole bunch of points
- * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
+ * \param first_point If true then this point is the first one from a whole bunch of points
+ * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
* \param snappers List of snappers to try to snap to
* \return Snapped point.
*/
@@ -123,7 +123,7 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point
bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- Inkscape::SnappedPoint const s = freeSnap(point_type, p, first_point, bbox_to_snap);
+ Inkscape::SnappedPoint const s = freeSnap(point_type, p, first_point, bbox_to_snap);
s.getPoint(p);
}
@@ -132,8 +132,8 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point
*
* \param point_type Type of point.
* \param p Point.
- * \param first_point If true then this point is the first one from a whole bunch of points
- * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
+ * \param first_point If true then this point is the first one from a whole bunch of points
+ * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
* \param snappers List of snappers to try to snap to
* \return Snapped point.
*/
@@ -146,28 +146,28 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
if (!someSnapperMightSnap()) {
return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
-
+
std::vector<SPItem const *> *items_to_ignore;
- if (_item_to_ignore) { // If we have only a single item to ignore
- // then build a list containing this single item;
+ if (_item_to_ignore) { // If we have only a single item to ignore
+ // then build a list containing this single item;
// This single-item list will prevail over any other _items_to_ignore list, should that exist
items_to_ignore = new std::vector<SPItem const *>;
items_to_ignore->push_back(_item_to_ignore);
} else {
items_to_ignore = _items_to_ignore;
}
-
+
SnappedConstraints sc;
SnapperList const snappers = getSnappers();
-
+
for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
(*i)->freeSnap(sc, point_type, p, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes);
}
-
+
if (_item_to_ignore) {
- delete items_to_ignore;
+ delete items_to_ignore;
}
-
+
return findBestSnap(p, sc, false);
}
@@ -179,51 +179,51 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
// PS: Wether we really find a multiple also depends on the snapping range!
Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
{
- if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here
+ if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here
return t;
-
+
//FIXME: this code should actually do this: add new grid snappers that are active for this desktop. now it just adds all gridsnappers
SPDesktop* desktop = SP_ACTIVE_DESKTOP;
-
+
if (desktop && desktop->gridsEnabled()) {
bool success = false;
- Geom::Point nearest_multiple;
+ Geom::Point nearest_multiple;
Geom::Coord nearest_distance = NR_HUGE;
-
+
// It will snap to the grid for which we find the closest snap. This might be a different
- // grid than to which the objects were initially aligned. I don't see an easy way to fix
- // this, so when using multiple grids one can get unexpected results
-
+ // grid than to which the objects were initially aligned. I don't see an easy way to fix
+ // this, so when using multiple grids one can get unexpected results
+
// Cannot use getGridSnappers() because we need both the grids AND their snappers
- // Therefor we iterate through all grids manually
+ // Therefor we iterate through all grids manually
for (GSList const *l = _named_view->grids; l != NULL; l = l->next) {
Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
- const Inkscape::Snapper* snapper = grid->snapper;
+ const Inkscape::Snapper* snapper = grid->snapper;
if (snapper && snapper->ThisSnapperMightSnap()) {
- // To find the nearest multiple of the grid pitch for a given translation t, we
+ // To find the nearest multiple of the grid pitch for a given translation t, we
// will use the grid snapper. Simply snapping the value t to the grid will do, but
// only if the origin of the grid is at (0,0). If it's not then compensate for this
// in the translation t
Geom::Point const t_offset = from_2geom(t) + grid->origin;
- SnappedConstraints sc;
+ SnappedConstraints sc;
// Only the first three parameters are being used for grid snappers
snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, TRUE, Geom::OptRect(), NULL, NULL);
// Find the best snap for this grid, including intersections of the grid-lines
Inkscape::SnappedPoint s = findBestSnap(t_offset, sc, false);
- if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
- // use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
- // doesn't tell us anything about which node to snap
- success = true;
+ if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
+ // use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
+ // doesn't tell us anything about which node to snap
+ success = true;
nearest_multiple = s.getPoint() - to_2geom(grid->origin);
nearest_distance = s.getSnapDistance();
}
}
}
-
- if (success)
+
+ if (success)
return nearest_multiple;
}
-
+
return t;
}
*
* \param point_type Type of point.
* \param p Point.
- * \param first_point If true then this point is the first one from a whole bunch of points
- * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
+ * \param first_point If true then this point is the first one from a whole bunch of points
+ * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
* \param constraint Constraint line.
* \return Snapped point.
*/
@@ -245,7 +245,7 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, constraint, first_point, bbox_to_snap);
+ Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, constraint, first_point, bbox_to_snap);
s.getPoint(p);
}
@@ -255,8 +255,8 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
*
* \param point_type Type of point.
* \param p Point.
- * \param first_point If true then this point is the first one from a whole bunch of points
- * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
+ * \param first_point If true then this point is the first one from a whole bunch of points
+ * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation
* \param constraint Constraint line.
* \return Snapped point.
*/
@@ -270,41 +270,41 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
if (!someSnapperMightSnap()) {
return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
-
+
std::vector<SPItem const *> *items_to_ignore;
- if (_item_to_ignore) { // If we have only a single item to ignore
- // then build a list containing this single item;
+ if (_item_to_ignore) { // If we have only a single item to ignore
+ // then build a list containing this single item;
// This single-item list will prevail over any other _items_to_ignore list, should that exist
items_to_ignore = new std::vector<SPItem const *>;
items_to_ignore->push_back(_item_to_ignore);
} else {
items_to_ignore = _items_to_ignore;
}
-
- SnappedConstraints sc;
+
+ SnappedConstraints sc;
SnapperList const snappers = getSnappers();
for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
(*i)->constrainedSnap(sc, point_type, p, first_point, bbox_to_snap, constraint, items_to_ignore);
}
-
+
if (_item_to_ignore) {
- delete items_to_ignore;
+ delete items_to_ignore;
}
-
+
return findBestSnap(p, sc, true);
}
void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const
{
// This method is used to snap a guide to nodes, while dragging the guide around
-
+
if ( !(object.GuidesMightSnap() && snapprefs.getSnapEnabledGlobally()) || snapprefs.getSnapPostponedGlobally() ) {
- return;
+ return;
}
-
+
SnappedConstraints sc;
object.guideSnap(sc, p, guide_normal);
-
+
Inkscape::SnappedPoint const s = findBestSnap(p, sc, false);
s.getPoint(p);
}
*/
/* Quick check to see if we have any snappers that are enabled
- ** Also used to globally disable all snapping
+ ** Also used to globally disable all snapping
*/
if (someSnapperMightSnap() == false) {
return Inkscape::SnappedPoint();
}
-
+
std::vector<Geom::Point> transformed_points;
Geom::Rect bbox;
-
+
for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
/* Work out the transformed version of this point */
Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform);
-
+
// add the current transformed point to the box hulling all transformed points
if (i == points.begin()) {
- bbox = Geom::Rect(transformed, transformed);
+ bbox = Geom::Rect(transformed, transformed);
} else {
bbox.expandTo(transformed);
}
-
+
transformed_points.push_back(transformed);
- }
-
+ }
+
/* The current best transformation */
Geom::Point best_transformation = transformation;
// std::cout << std::endl;
for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
-
- /* Snap it */
+
+ /* Snap it */
Inkscape::SnappedPoint snapped_point;
Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
Geom::Point const b = (*i - origin); // vector to original point
-
- if (constrained) {
+
+ if (constrained) {
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
+ // calculate that line here
dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, b);
} else if (transformation_type == STRETCH) { // when non-uniform stretching {
dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]);
// When doing a constrained translation, all points will move in the same direction, i.e.
// either horizontally or vertically. The lines along which they move are therefore all
// parallel, but might not be colinear. Therefore we will have to set the point through
- // which the constraint-line runs here, for each point individually.
+ // which the constraint-line runs here, for each point individually.
dedicated_constraint.setPoint(*i);
- } // else: leave the original constraint, e.g. for skewing
+ } // else: leave the original constraint, e.g. for skewing
if (transformation_type == SCALE && !uniform) {
- g_warning("Non-uniform constrained scaling is not supported!");
+ g_warning("Non-uniform constrained scaling is not supported!");
}
snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
} else {
bool const c1 = fabs(b[Geom::X]) < 1e-6;
bool const c2 = fabs(b[Geom::Y]) < 1e-6;
- if (transformation_type == SCALE && (c1 || c2) && !(c1 && c2)) {
- // When scaling, a point aligned either horizontally or vertically with the origin can only
- // move in that specific direction; therefore it should only snap in that direction, otherwise
- // we will get snapped points with an invalid transformation
- dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]);
- snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
+ if (transformation_type == SCALE && (c1 || c2) && !(c1 && c2)) {
+ // When scaling, a point aligned either horizontally or vertically with the origin can only
+ // move in that specific direction; therefore it should only snap in that direction, otherwise
+ // we will get snapped points with an invalid transformation
+ dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]);
+ snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
} else {
- snapped_point = freeSnap(type, *j, i == points.begin(), bbox);
+ snapped_point = freeSnap(type, *j, i == points.begin(), bbox);
}
}
// std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl;
Geom::Point result;
Geom::Point scale_metric(NR_HUGE, NR_HUGE);
-
+
if (snapped_point.getSnapped()) {
/* We snapped. Find the transformation that describes where the snapped point has
** ended up, and also the metric for this transformation.
*/
Geom::Point const a = (snapped_point.getPoint() - origin); // vector to snapped point
//Geom::Point const b = (*i - origin); // vector to original point
-
+
switch (transformation_type) {
case TRANSLATION:
result = snapped_point.getPoint() - *i;
- /* Consider the case in which a box is almost aligned with a grid in both
+ /* Consider the case in which a box is almost aligned with a grid in both
* horizontal and vertical directions. The distance to the intersection of
* the grid lines will always be larger then the distance to a single grid
- * line. If we prefer snapping to an intersection instead of to a single
+ * line. If we prefer snapping to an intersection instead of to a single
* grid line, then we cannot use "metric = Geom::L2(result)". Therefore the
* snapped distance will be used as a metric. Please note that the snapped
* distance is defined as the distance to the nearest line of the intersection,
- * and not to the intersection itself!
+ * and not to the intersection itself!
*/
// Only for translations, the relevant metric will be the real snapped distance,
// so we don't have to do anything special here
{
result = Geom::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
+ // the origin of the scaling, then it will scale purely in X or Y
// We can therefore only calculate the scaling in this direction
// and the scaling factor for the other direction should remain
// untouched (unless scaling is uniform ofcourse)
result[0] = (snapped_point.getPoint()[dim] - (*i)[dim]) / ((*i)[1 - dim] - origin[1 - dim]); // skew factor
result[1] = transformation[1]; // scale factor
// Store the metric for this transformation as a virtual distance
- snapped_point.setSnapDistance(std::abs(result[0] - transformation[0]));
+ snapped_point.setSnapDistance(std::abs(result[0] - transformation[0]));
snapped_point.setSecondSnapDistance(NR_HUGE);
break;
default:
g_assert_not_reached();
}
-
+
// When scaling, we're considering the best transformation in each direction separately. We will have a metric in each
// direction, whereas for all other transformation we only a single one-dimensional metric. That's why we need to handle
// the scaling metric differently
best_scale_metric[index] = fabs(scale_metric[index]);
// When scaling, we're considering the best transformation in each direction separately
// Therefore two different snapped points might together make a single best transformation
- // We will however return only a single snapped point (e.g. to display the snapping indicator)
+ // We will however return only a single snapped point (e.g. to display the snapping indicator)
best_snapped_point = snapped_point;
// std::cout << "SEL ";
} // else { std::cout << " ";}
if (uniform) {
if (best_scale_metric[0] < best_scale_metric[1]) {
best_transformation[1] = best_transformation[0];
- best_scale_metric[1] = best_scale_metric[0];
+ best_scale_metric[1] = best_scale_metric[0];
} else {
best_transformation[0] = best_transformation[1];
best_scale_metric[0] = best_scale_metric[1];
}
} else { // For all transformations other than scaling
if (best_snapped_point.isOtherSnapBetter(snapped_point, true)) {
- best_transformation = result;
- best_snapped_point = snapped_point;
+ best_transformation = result;
+ best_snapped_point = snapped_point;
}
}
}
-
+
j++;
}
-
+
Geom::Coord best_metric;
if (transformation_type == SCALE) {
// When scaling, don't ever exit with one of scaling components set to NR_HUGE
if (uniform && best_transformation[1-index] < NR_HUGE) {
best_transformation[index] = best_transformation[1-index];
} else {
- best_transformation[index] = transformation[index];
+ best_transformation[index] = transformation[index];
}
}
}
best_metric = std::min(best_scale_metric[0], best_scale_metric[1]);
} else { // For all transformations other than scaling
- best_metric = best_snapped_point.getSnapDistance();
+ best_metric = best_snapped_point.getSnapDistance();
}
-
+
best_snapped_point.setTransformation(best_transformation);
// Using " < 1e6" instead of " < NR_HUGE" for catching some rounding errors
- // These rounding errors might be caused by NRRects, see bug #1584301
+ // These rounding errors might be caused by NRRects, see bug #1584301
best_snapped_point.setSnapDistance(best_metric < 1e6 ? best_metric : NR_HUGE);
return best_snapped_point;
}
@@ -572,11 +572,11 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference
Geom::Point const &pointer,
Geom::Point const &tr) const
{
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
- }
-
- return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
}
@@ -598,11 +598,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &tr) const
{
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
- }
-
- return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
}
@@ -623,11 +623,11 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi
Geom::Scale const &s,
Geom::Point const &o) const
{
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false));
- }
-
- return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
}
@@ -650,11 +650,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc
Geom::Point const &o) const
{
// When constrained scaling, only uniform scaling is supported.
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true));
- }
-
- return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
}
@@ -679,11 +679,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
Geom::Dim2 d,
bool u) const
{
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u));
- }
-
- return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
}
@@ -703,29 +703,29 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
std::vector<Geom::Point> const &p,
Geom::Point const &pointer,
Inkscape::Snapper::ConstraintLine const &constraint,
- Geom::Point const &s,
+ Geom::Point const &s,
Geom::Point const &o,
Geom::Dim2 d) const
{
- // "s" contains skew factor in s[0], and scale factor in s[1]
-
- // Snapping the nodes of the boundingbox of a selection that is being transformed, will only work if
- // the transformation of the bounding box is equal to the transformation of the individual nodes. This is
- // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew,
- // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping
- // of bounding boxes is not allowed here.
- g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
-
- if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SKEW, s, o, d, false));
- }
-
- return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
+ // "s" contains skew factor in s[0], and scale factor in s[1]
+
+ // Snapping the nodes of the boundingbox of a selection that is being transformed, will only work if
+ // the transformation of the bounding box is equal to the transformation of the individual nodes. This is
+ // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew,
+ // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping
+ // of bounding boxes is not allowed here.
+ g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
+
+ if (p.size() == 1) {
+ _displaySnapsource(point_type, _transformPoint(p.at(0), SKEW, s, o, d, false));
+ }
+
+ return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
}
Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const
{
-
+
/*
std::cout << "Type and number of snapped constraints: " << std::endl;
std::cout << " Points : " << sc.points.size() << std::endl;
@@ -734,47 +734,47 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
std::cout << " Guide lines : " << sc.guide_lines.size()<< std::endl;
std::cout << " Curves : " << sc.curves.size()<< std::endl;
*/
-
+
// Store all snappoints
std::list<Inkscape::SnappedPoint> sp_list;
-
+
// search for the closest snapped point
Inkscape::SnappedPoint closestPoint;
if (getClosestSP(sc.points, closestPoint)) {
sp_list.push_back(closestPoint);
- }
-
+ }
+
// search for the closest snapped curve
Inkscape::SnappedCurve closestCurve;
- if (getClosestCurve(sc.curves, closestCurve)) {
+ if (getClosestCurve(sc.curves, closestCurve)) {
sp_list.push_back(Inkscape::SnappedPoint(closestCurve));
}
-
+
if (snapprefs.getSnapIntersectionCS()) {
// search for the closest snapped intersection of curves
Inkscape::SnappedPoint closestCurvesIntersection;
if (getClosestIntersectionCS(sc.curves, p, closestCurvesIntersection)) {
sp_list.push_back(closestCurvesIntersection);
}
- }
+ }
// search for the closest snapped grid line
Inkscape::SnappedLine closestGridLine;
- if (getClosestSL(sc.grid_lines, closestGridLine)) {
+ if (getClosestSL(sc.grid_lines, closestGridLine)) {
closestGridLine.setTarget(Inkscape::SNAPTARGET_GRID);
sp_list.push_back(Inkscape::SnappedPoint(closestGridLine));
}
-
+
// search for the closest snapped guide line
Inkscape::SnappedLine closestGuideLine;
if (getClosestSL(sc.guide_lines, closestGuideLine)) {
closestGuideLine.setTarget(Inkscape::SNAPTARGET_GUIDE);
sp_list.push_back(Inkscape::SnappedPoint(closestGuideLine));
}
-
+
// When freely snapping to a grid/guide/path, only one degree of freedom is eliminated
- // Therefore we will try get fully constrained by finding an intersection with another grid/guide/path
-
+ // Therefore we will try get fully constrained by finding an intersection with another grid/guide/path
+
// When doing a constrained snap however, we're already at an intersection of the constrained line and
// the grid/guide/path we're snapping to. This snappoint is therefore fully constrained, so there's
// no need to look for additional intersections
@@ -785,14 +785,14 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
sp_list.push_back(closestGridPoint);
}
-
+
// search for the closest snapped intersection of guide lines
Inkscape::SnappedPoint closestGuidePoint;
if (getClosestIntersectionSL(sc.guide_lines, closestGuidePoint)) {
closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
sp_list.push_back(closestGuidePoint);
}
-
+
// search for the closest snapped intersection of grid with guide lines
if (snapprefs.getSnapIntersectionGG()) {
Inkscape::SnappedPoint closestGridGuidePoint;
@@ -802,23 +802,23 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
}
}
}
-
+
// now let's see which snapped point gets a thumbs up
Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
// std::cout << "Finding the best snap..." << std::endl;
for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
// first find out if this snapped point is within snapping range
- // std::cout << "sp = " << from_2geom((*i).getPoint());
+ // std::cout << "sp = " << from_2geom((*i).getPoint());
if ((*i).getSnapDistance() <= (*i).getTolerance()) {
// if it's the first point, or if it is closer than the best snapped point so far
- if (i == sp_list.begin() || bestSnappedPoint.isOtherSnapBetter(*i, false)) {
+ if (i == sp_list.begin() || bestSnappedPoint.isOtherSnapBetter(*i, false)) {
// then prefer this point over the previous one
bestSnappedPoint = *i;
}
}
// std::cout << std::endl;
- }
-
+ }
+
// Update the snap indicator, if requested
if (_snapindicator) {
if (bestSnappedPoint.getSnapped()) {
@@ -827,9 +827,9 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
_desktop->snapindicator->remove_snaptarget();
}
}
-
+
// std::cout << "findBestSnap = " << bestSnappedPoint.getPoint() << " | dist = " << bestSnappedPoint.getSnapDistance() << std::endl;
- return bestSnappedPoint;
+ return bestSnappedPoint;
}
void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem const *item_to_ignore, std::vector<Geom::Point> *unselected_nodes)
@@ -849,7 +849,7 @@ void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, std::vecto
_items_to_ignore = &items_to_ignore;
_desktop = desktop;
_snapindicator = snapindicator;
- _unselected_nodes = unselected_nodes;
+ _unselected_nodes = unselected_nodes;
}
SPDocument *SnapManager::getDocument() const
return _named_view->document;
}
-Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
- Transformation const transformation_type,
- Geom::Point const &transformation,
- Geom::Point const &origin,
- Geom::Dim2 const dim,
- bool const uniform) const
+Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
+ Transformation const transformation_type,
+ Geom::Point const &transformation,
+ Geom::Point const &origin,
+ Geom::Dim2 const dim,
+ bool const uniform) const
{
- /* Work out the transformed version of this point */
+ /* Work out the transformed version of this point */
Geom::Point transformed;
switch (transformation_type) {
case TRANSLATION:
default:
g_assert_not_reached();
}
-
+
return transformed;
}
void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if (prefs->getBool("/options/snapclosestonly/value")) {
- bool p_is_a_node = point_type & Inkscape::SnapPreferences::SNAPPOINT_NODE;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getBool("/options/snapclosestonly/value")) {
+ bool p_is_a_node = point_type & Inkscape::SnapPreferences::SNAPPOINT_NODE;
bool p_is_a_bbox = point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX;
- if ((p_is_a_node && snapprefs.getSnapModeNode()) || (p_is_a_bbox && snapprefs.getSnapModeBBox())) {
- _desktop->snapindicator->set_new_snapsource(p);
- } else {
- _desktop->snapindicator->remove_snapsource();
- }
- }
+ if ((p_is_a_node && snapprefs.getSnapModeNode()) || (p_is_a_bbox && snapprefs.getSnapModeBBox())) {
+ _desktop->snapindicator->set_new_snapsource(p);
+ } else {
+ _desktop->snapindicator->remove_snapsource();
+ }
+ }
}
/*
diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp
index b566bfe34c7704a44282ca184d3165cf0a3a3ab5..7b65c5c655b0751f46d64a77008b000ed6d62b10 100644 (file)
--- a/src/snapped-curve.cpp
+++ b/src/snapped-curve.cpp
Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve)
{
- _distance = snapped_distance;
+ _distance = snapped_distance;
_tolerance = std::max(snapped_tolerance, 1.0);
_always_snap = always_snap;
_curve = curve;
_fully_constrained = fully_constrained;
}
-Inkscape::SnappedCurve::SnappedCurve()
+Inkscape::SnappedCurve::SnappedCurve()
{
_distance = NR_HUGE;
_tolerance = 1;
{
}
-Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &curve, Geom::Point const &p) const
+Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &curve, Geom::Point const &p) const
{
// Calculate the intersections of two curves, which are both within snapping range, and
// return only the closest intersection
// PS: We need p (the location of the mouse pointer) for find out which intersection is the
// closest, as there might be multiple intersections of two curves
Geom::Crossings cs = crossings(*(this->_curve), *(curve._curve));
-
+
if (cs.size() > 0) {
// There might be multiple intersections: find the closest
Geom::Coord best_dist = NR_HUGE;
best_p = p_ix;
}
}
-
- // Now we've found the closests intersection, return it as a SnappedPoint
+
+ // Now we've found the closest intersection, return it as a SnappedPoint
bool const use_this_as_primary = _distance < curve.getSnapDistance();
Inkscape::SnappedCurve const *primaryC = use_this_as_primary ? this : &curve;
Inkscape::SnappedCurve const *secondaryC = use_this_as_primary ? &curve : this;
@@ -80,37 +80,40 @@ Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &cur
// we need a desktop: this is a dirty hack
SPDesktop const *desktop = SP_ACTIVE_DESKTOP;
best_p = desktop->dt2doc(best_p);
+
+ Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(best_p - this->getPoint()) : Geom::L2(best_p - curve.getPoint());
+ Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(best_p - curve.getPoint()) : Geom::L2(best_p - this->getPoint());
// TODO: Investigate whether it is possible to use document coordinates everywhere
// in the snapper code. Only the mouse position should be in desktop coordinates, I guess.
// All paths are already in document coords and we are certainly not going to change THAT.
- return SnappedPoint(from_2geom(best_p), Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryC->getSnapDistance(), primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
- secondaryC->getSnapDistance(), secondaryC->getTolerance(), secondaryC->getAlwaysSnap());
+ return SnappedPoint(from_2geom(best_p), Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
+ secondaryDist, secondaryC->getTolerance(), secondaryC->getAlwaysSnap());
}
-
+
// No intersection
return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
}
// search for the closest snapped line
-bool getClosestCurve(std::list<Inkscape::SnappedCurve> const &list, Inkscape::SnappedCurve &result)
+bool getClosestCurve(std::list<Inkscape::SnappedCurve> const &list, Inkscape::SnappedCurve &result)
{
bool success = false;
-
+
for (std::list<Inkscape::SnappedCurve>::const_iterator i = list.begin(); i != list.end(); i++) {
if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) {
result = *i;
success = true;
- }
+ }
}
-
- return success;
+
+ return success;
}
// search for the closest intersection of two snapped curves, which are both member of the same collection
bool getClosestIntersectionCS(std::list<Inkscape::SnappedCurve> const &list, Geom::Point const &p, Inkscape::SnappedPoint &result)
{
bool success = false;
-
+
for (std::list<Inkscape::SnappedCurve>::const_iterator i = list.begin(); i != list.end(); i++) {
std::list<Inkscape::SnappedCurve>::const_iterator j = i;
j++;
@@ -119,21 +122,21 @@ bool getClosestIntersectionCS(std::list<Inkscape::SnappedCurve> const &list, Geo
if (sp.getAtIntersection()) {
// if it's the first point
bool const c1 = !success;
- // or, if it's closer
+ // or, if it's closer
bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
- // or, if it's just as close then look at the other distance
+ // or, if it's just as close then look at the other distance
// (only relevant for snapped points which are at an intersection)
- bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
+ bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
// then prefer this point over the previous one
- if (c1 || c2 || c3) {
+ if (c1 || c2 || c3) {
result = sp;
success = true;
}
- }
+ }
}
}
-
- return success;
+
+ return success;
}
/*
Local Variables:
diff --git a/src/snapped-line.cpp b/src/snapped-line.cpp
index 48fc8205132161ee44f7c174487e632d2586b965..5f7d5407b5e9e8f2afdcecb77b6de4d245087380 100644 (file)
--- a/src/snapped-line.cpp
+++ b/src/snapped-line.cpp
#include "libnr/nr-values.h"
Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
- : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line)
+ : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line)
{
- _point = snapped_point;
+ _point = snapped_point;
_distance = snapped_distance;
- _tolerance = std::max(snapped_tolerance, 1.0);
+ _tolerance = std::max(snapped_tolerance, 1.0);
_always_snap = always_snap;
- _at_intersection = false;
- _second_distance = NR_HUGE;
+ _at_intersection = false;
+ _second_distance = NR_HUGE;
_second_tolerance = 1;
_second_always_snap = false;
}
-Inkscape::SnappedLineSegment::SnappedLineSegment()
+Inkscape::SnappedLineSegment::SnappedLineSegment()
{
- _start_point_of_line = Geom::Point(0,0);
- _end_point_of_line = Geom::Point(0,0);
- _point = Geom::Point(0,0);
+ _start_point_of_line = Geom::Point(0,0);
+ _end_point_of_line = Geom::Point(0,0);
+ _point = Geom::Point(0,0);
_distance = NR_HUGE;
- _tolerance = 1;
+ _tolerance = 1;
_always_snap = false;
- _at_intersection = false;
- _second_distance = NR_HUGE;
+ _at_intersection = false;
+ _second_distance = NR_HUGE;
_second_tolerance = 1;
_second_always_snap = false;
}
{
}
-Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegment const &line) const
+Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegment const &line) const
{
- Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
- Geom::IntersectorKind result = segment_intersect(_start_point_of_line, _end_point_of_line,
- line._start_point_of_line, line._end_point_of_line,
- intersection_2geom);
- Geom::Point intersection(intersection_2geom);
-
- if (result == Geom::intersects) {
- /* If a snapper has been told to "always snap", then this one should be preferred
+ Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
+ Geom::IntersectorKind result = segment_intersect(_start_point_of_line, _end_point_of_line,
+ line._start_point_of_line, line._end_point_of_line,
+ intersection_2geom);
+ Geom::Point intersection(intersection_2geom);
+
+ if (result == Geom::intersects) {
+ /* If a snapper has been told to "always snap", then this one should be preferred
* over the other, if that other one has not been told so. (The preferred snapper
* will be labelled "primary" below)
*/
bool const c1 = this->getAlwaysSnap() && !line.getAlwaysSnap(); //do not use _tolerance directly!
/* If neither or both have been told to "always snap", then cast a vote based on
* the snapped distance. For this we should consider the distance to the snapped
- * line, not the distance to the intersection.
+ * line, not the distance to the intersection.
* See the comment in Inkscape::SnappedLine::intersect
- */
+ */
bool const c2 = _distance < line.getSnapDistance();
bool const use_this_as_primary = c1 || c2;
Inkscape::SnappedLineSegment const *primarySLS = use_this_as_primary ? this : &line;
Inkscape::SnappedLineSegment const *secondarySLS = use_this_as_primary ? &line : this;
- return SnappedPoint(intersection, SNAPTARGET_PATH_INTERSECTION, primarySLS->getSnapDistance(), primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
- secondarySLS->getSnapDistance(), secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap());
- }
-
+ Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
+ Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
+ return SnappedPoint(intersection, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
+ secondaryDist, secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap());
+ }
+
// No intersection
return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
};
@@ -80,46 +82,46 @@ Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegmen
Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line)
: _normal_to_line(normal_to_line), _point_on_line(point_on_line)
{
- _distance = snapped_distance;
+ _distance = snapped_distance;
_tolerance = std::max(snapped_tolerance, 1.0);
_always_snap = always_snap;
- _second_distance = NR_HUGE;
+ _second_distance = NR_HUGE;
_second_tolerance = 1;
_second_always_snap = false;
- _point = snapped_point;
- _at_intersection = false;
+ _point = snapped_point;
+ _at_intersection = false;
}
-Inkscape::SnappedLine::SnappedLine()
+Inkscape::SnappedLine::SnappedLine()
{
- _normal_to_line = Geom::Point(0,0);
- _point_on_line = Geom::Point(0,0);
- _distance = NR_HUGE;
+ _normal_to_line = Geom::Point(0,0);
+ _point_on_line = Geom::Point(0,0);
+ _distance = NR_HUGE;
_tolerance = 1;
_always_snap = false;
- _second_distance = NR_HUGE;
+ _second_distance = NR_HUGE;
_second_tolerance = 1;
_second_always_snap = false;
- _point = Geom::Point(0,0);
- _at_intersection = false;
+ _point = Geom::Point(0,0);
+ _at_intersection = false;
}
Inkscape::SnappedLine::~SnappedLine()
{
}
-Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line) const
+Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line) const
{
- // Calculate the intersection of two lines, which are both within snapping range
+ // Calculate the intersection of two lines, which are both within snapping range
// One could be a grid line, whereas the other could be a guide line
- // The point of intersection should be considered for snapping, but might be outside the snapping range
-
- Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
- Geom::IntersectorKind result = Geom::line_intersection(getNormal(), getConstTerm(),
+ // The point of intersection should be considered for snapping, but might be outside the snapping range
+
+ Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
+ Geom::IntersectorKind result = Geom::line_intersection(getNormal(), getConstTerm(),
line.getNormal(), line.getConstTerm(), intersection_2geom);
- Geom::Point intersection(intersection_2geom);
-
- if (result == Geom::intersects) {
+ Geom::Point intersection(intersection_2geom);
+
+ if (result == Geom::intersects) {
/* If a snapper has been told to "always snap", then this one should be preferred
* over the other, if that other one has not been told so. (The preferred snapper
* will be labelled "primary" below)
@@ -127,147 +129,140 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line)
bool const c1 = this->getAlwaysSnap() && !line.getAlwaysSnap();
/* If neither or both have been told to "always snap", then cast a vote based on
* the snapped distance. For this we should consider the distance to the snapped
- * line, not the distance to the intersection.
- *
- * The relevant snapped distance is the distance to the closest snapped line, not the
- * distance to the intersection. For example, when a box is almost aligned with a grid
- * in both horizontal and vertical directions, the distance to the intersection of the
- * grid lines will always be larger then the distance to a grid line. We will be snapping
- * to the closest snapped point however, so if we ever want to snap to the intersection
- * then the distance to it should at least be equal to the other distance, not greater
- * than it, as that would rule the intersection out when comparing it with regular snappoint,
- * as the latter will always be closer
- */
+ * line or to the intersection
+ */
bool const c2 = _distance < line.getSnapDistance();
bool const use_this_as_primary = c1 || c2;
Inkscape::SnappedLine const *primarySL = use_this_as_primary ? this : &line;
Inkscape::SnappedLine const *secondarySL = use_this_as_primary ? &line : this;
- return SnappedPoint(intersection, Inkscape::SNAPTARGET_UNDEFINED, primarySL->getSnapDistance(), primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
- secondarySL->getSnapDistance(), secondarySL->getTolerance(), secondarySL->getAlwaysSnap());
- // The type of the snap target is yet undefined, as we cannot tell whether
- // we're snapping to grid or the guide lines; must be set by on a higher level
+ Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
+ Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
+ return SnappedPoint(intersection, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
+ secondaryDist, secondarySL->getTolerance(), secondarySL->getAlwaysSnap());
+ // The type of the snap target is yet undefined, as we cannot tell whether
+ // we're snapping to grid or the guide lines; must be set by on a higher level
}
-
+
// No intersection
return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
}
// search for the closest snapped line segment
-bool getClosestSLS(std::list<Inkscape::SnappedLineSegment> const &list, Inkscape::SnappedLineSegment &result)
+bool getClosestSLS(std::list<Inkscape::SnappedLineSegment> const &list, Inkscape::SnappedLineSegment &result)
{
- bool success = false;
-
- for (std::list<Inkscape::SnappedLineSegment>::const_iterator i = list.begin(); i != list.end(); i++) {
- if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) {
- result = *i;
- success = true;
- }
- }
-
- return success;
+ bool success = false;
+
+ for (std::list<Inkscape::SnappedLineSegment>::const_iterator i = list.begin(); i != list.end(); i++) {
+ if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) {
+ result = *i;
+ success = true;
+ }
+ }
+
+ return success;
}
// search for the closest intersection of two snapped line segments, which are both member of the same collection
bool getClosestIntersectionSLS(std::list<Inkscape::SnappedLineSegment> const &list, Inkscape::SnappedPoint &result)
{
- bool success = false;
-
- for (std::list<Inkscape::SnappedLineSegment>::const_iterator i = list.begin(); i != list.end(); i++) {
- std::list<Inkscape::SnappedLineSegment>::const_iterator j = i;
- j++;
- for (; j != list.end(); j++) {
- Inkscape::SnappedPoint sp = (*i).intersect(*j);
- if (sp.getAtIntersection()) {
- // if it's the first point
- bool const c1 = !success;
- // or, if it's closer
- bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
- // or, if it's just then look at the other distance
- // (only relevant for snapped points which are at an intersection
- bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
- // then prefer this point over the previous one
- if (c1 || c2 || c3) {
- result = sp;
- success = true;
- }
- }
- }
- }
-
- return success;
+ bool success = false;
+
+ for (std::list<Inkscape::SnappedLineSegment>::const_iterator i = list.begin(); i != list.end(); i++) {
+ std::list<Inkscape::SnappedLineSegment>::const_iterator j = i;
+ j++;
+ for (; j != list.end(); j++) {
+ Inkscape::SnappedPoint sp = (*i).intersect(*j);
+ if (sp.getAtIntersection()) {
+ // if it's the first point
+ bool const c1 = !success;
+ // or, if it's closer
+ bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
+ // or, if it's just then look at the other distance
+ // (only relevant for snapped points which are at an intersection
+ bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
+ // then prefer this point over the previous one
+ if (c1 || c2 || c3) {
+ result = sp;
+ success = true;
+ }
+ }
+ }
+ }
+
+ return success;
}
// search for the closest snapped line
-bool getClosestSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedLine &result)
+bool getClosestSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedLine &result)
{
- bool success = false;
-
- for (std::list<Inkscape::SnappedLine>::const_iterator i = list.begin(); i != list.end(); i++) {
- if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) {
- result = *i;
- success = true;
- }
- }
-
- return success;
+ bool success = false;
+
+ for (std::list<Inkscape::SnappedLine>::const_iterator i = list.begin(); i != list.end(); i++) {
+ if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) {
+ result = *i;
+ success = true;
+ }
+ }
+
+ return success;
}
// search for the closest intersection of two snapped lines, which are both member of the same collection
bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedPoint &result)
{
- bool success = false;
-
- for (std::list<Inkscape::SnappedLine>::const_iterator i = list.begin(); i != list.end(); i++) {
- std::list<Inkscape::SnappedLine>::const_iterator j = i;
- j++;
- for (; j != list.end(); j++) {
- Inkscape::SnappedPoint sp = (*i).intersect(*j);
- if (sp.getAtIntersection()) {
- // if it's the first point
- bool const c1 = !success;
- // or, if it's closer
- bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
- // or, if it's just then look at the other distance
- // (only relevant for snapped points which are at an intersection
- bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
- // then prefer this point over the previous one
- if (c1 || c2 || c3) {
- result = sp;
- success = true;
- }
- }
- }
- }
-
- return success;
+ bool success = false;
+
+ for (std::list<Inkscape::SnappedLine>::const_iterator i = list.begin(); i != list.end(); i++) {
+ std::list<Inkscape::SnappedLine>::const_iterator j = i;
+ j++;
+ for (; j != list.end(); j++) {
+ Inkscape::SnappedPoint sp = (*i).intersect(*j);
+ if (sp.getAtIntersection()) {
+ // if it's the first point
+ bool const c1 = !success;
+ // or, if it's closer
+ bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
+ // or, if it's just then look at the other distance
+ // (only relevant for snapped points which are at an intersection
+ bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
+ // then prefer this point over the previous one
+ if (c1 || c2 || c3) {
+ result = sp;
+ success = true;
+ }
+ }
+ }
+ }
+
+ return success;
}
// search for the closest intersection of two snapped lines, which are in two different collections
bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list1, std::list<Inkscape::SnappedLine> const &list2, Inkscape::SnappedPoint &result)
{
- bool success = false;
-
- for (std::list<Inkscape::SnappedLine>::const_iterator i = list1.begin(); i != list1.end(); i++) {
- for (std::list<Inkscape::SnappedLine>::const_iterator j = list2.begin(); j != list2.end(); j++) {
- Inkscape::SnappedPoint sp = (*i).intersect(*j);
- if (sp.getAtIntersection()) {
- // if it's the first point
- bool const c1 = !success;
- // or, if it's closer
- bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
- // or, if it's just then look at the other distance
- // (only relevant for snapped points which are at an intersection
- bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
- // then prefer this point over the previous one
- if (c1 || c2 || c3) {
- result = sp;
- success = true;
- }
- }
- }
- }
-
- return success;
+ bool success = false;
+
+ for (std::list<Inkscape::SnappedLine>::const_iterator i = list1.begin(); i != list1.end(); i++) {
+ for (std::list<Inkscape::SnappedLine>::const_iterator j = list2.begin(); j != list2.end(); j++) {
+ Inkscape::SnappedPoint sp = (*i).intersect(*j);
+ if (sp.getAtIntersection()) {
+ // if it's the first point
+ bool const c1 = !success;
+ // or, if it's closer
+ bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
+ // or, if it's just then look at the other distance
+ // (only relevant for snapped points which are at an intersection
+ bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
+ // then prefer this point over the previous one
+ if (c1 || c2 || c3) {
+ result = sp;
+ success = true;
+ }
+ }
+ }
+ }
+
+ return success;
}
/*
diff --git a/src/snapped-point.cpp b/src/snapped-point.cpp
index c5eaba74992e3122c6530387613f26f582bf10bd..fc6e5e87f7d912599f7fbefefbbf1ba56d6270d2 100644 (file)
--- a/src/snapped-point.cpp
+++ b/src/snapped-point.cpp
Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
: _point(p), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
{
- // tolerance should never be smaller than 1 px, as it is used for normalization in isOtherSnapBetter. We don't want a division by zero.
+ // tolerance should never be smaller than 1 px, as it is used for normalization in isOtherSnapBetter. We don't want a division by zero.
_fully_constrained = fully_constrained;
_second_distance = NR_HUGE;
_second_tolerance = 1;
: _point(p), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a),
_second_distance(d2), _second_tolerance(std::max(t2,1.0)), _second_always_snap(a2)
{
- // tolerance should never be smaller than 1 px, as it is used for normalization in
+ // tolerance should never be smaller than 1 px, as it is used for normalization in
// isOtherSnapBetter. We don't want a division by zero.
_transformation = Geom::Point(1,1);
_pointer_distance = NR_HUGE;
Inkscape::SnappedPoint::SnappedPoint()
{
_point = Geom::Point(0,0);
- _target = SNAPTARGET_UNDEFINED,
+ _target = SNAPTARGET_UNDEFINED,
_distance = NR_HUGE;
_tolerance = 1;
_always_snap = false;
void Inkscape::SnappedPoint::getPoint(Geom::Point &p) const
{
// When we have snapped
- if (getSnapped()) {
+ if (getSnapped()) {
// then return the snapped point by overwriting p
p = _point;
} //otherwise p will be left untouched; this way the caller doesn't have to check wether we've snapped
@@ -81,55 +81,54 @@ bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoin
bool Inkscape::SnappedPoint::isOtherSnapBetter(Inkscape::SnappedPoint const &other_one, bool weighted) const
{
-
- double dist_other = other_one.getSnapDistance();
- double dist_this = getSnapDistance();
-
- // The distance to the pointer should only be taken into account when finding the best snapped source node (when
+
+ double dist_other = other_one.getSnapDistance();
+ double dist_this = getSnapDistance();
+
+ // The distance to the pointer should only be taken into account when finding the best snapped source node (when
// there's more than one). It is not useful when trying to find the best snapped target point.
// (both the snap distance and the pointer distance are measured in document pixels, not in screen pixels)
if (weighted) {
- // weigth factor: controls which node should be preferrerd for snapping, which is either
- // the node with the closest snap (w = 0), or the node closest to the mousepointer (w = 1)
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- double w = prefs->getDoubleLimited("/options/snapweight/value", 0.5, 0, 1);
- if (prefs->getBool("/options/snapclosestonly/value", false)) {
- w = 1;
- }
- if (w > 0) {
- // When accounting for the distance to the mouse pointer, then at least one of the snapped points should
- // have that distance set. If not, then this is a bug. Either "weighted" must be set to false, or the
- // mouse pointer distance must be set.
- g_assert(getPointerDistance() != NR_HUGE || other_one.getPointerDistance() != NR_HUGE);
- // The snap distance will always be smaller than the tolerance set for the snapper. The pointer distance can
- // however be very large. To compare these in a fair way, we will have to normalize these metrics first
- // The closest pointer distance will be normalized to 1.0; the other one will be > 1.0
- // The snap distance will be normalized to 1.0 if it's equal to the snapper tolerance
- double const norm_p = std::min(getPointerDistance(), other_one.getPointerDistance());
- double const norm_t_other = std::min(50.0, other_one.getTolerance());
- double const norm_t_this = std::min(50.0, getTolerance());
- dist_other = w * other_one.getPointerDistance() / norm_p + (1-w) * dist_other / norm_t_other;
- dist_this = w * getPointerDistance() / norm_p + (1-w) * dist_this / norm_t_this;
- }
- }
-
+ // weigth factor: controls which node should be preferrerd for snapping, which is either
+ // the node with the closest snap (w = 0), or the node closest to the mousepointer (w = 1)
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double w = prefs->getDoubleLimited("/options/snapweight/value", 0.5, 0, 1);
+ if (prefs->getBool("/options/snapclosestonly/value", false)) {
+ w = 1;
+ }
+ if (w > 0) {
+ // When accounting for the distance to the mouse pointer, then at least one of the snapped points should
+ // have that distance set. If not, then this is a bug. Either "weighted" must be set to false, or the
+ // mouse pointer distance must be set.
+ g_assert(getPointerDistance() != NR_HUGE || other_one.getPointerDistance() != NR_HUGE);
+ // The snap distance will always be smaller than the tolerance set for the snapper. The pointer distance can
+ // however be very large. To compare these in a fair way, we will have to normalize these metrics first
+ // The closest pointer distance will be normalized to 1.0; the other one will be > 1.0
+ // The snap distance will be normalized to 1.0 if it's equal to the snapper tolerance
+ double const norm_p = std::min(getPointerDistance(), other_one.getPointerDistance());
+ double const norm_t_other = std::min(50.0, other_one.getTolerance());
+ double const norm_t_this = std::min(50.0, getTolerance());
+ dist_other = w * other_one.getPointerDistance() / norm_p + (1-w) * dist_other / norm_t_other;
+ dist_this = w * getPointerDistance() / norm_p + (1-w) * dist_this / norm_t_this;
+ }
+ }
+
// If it's closer
bool c1 = dist_other < dist_this;
// or, if it's for a snapper with "always snap" turned on, and the previous wasn't
bool c2 = other_one.getAlwaysSnap() && !getAlwaysSnap();
// But in no case fall back from a snapper with "always snap" on to one with "always snap" off
bool c2n = !other_one.getAlwaysSnap() && getAlwaysSnap();
- // or, if we have a fully constrained snappoint (e.g. to a node), while the previous one was only partly constrained (e.g. to a line)
+ // or, if we have a fully constrained snappoint (e.g. to a node or an intersection), while the previous one was only partly constrained (e.g. to a line)
bool c3 = other_one.getFullyConstrained() && !getFullyConstrained();
- // But in no case fall back; (has less priority than c3n, so it is allowed to fall back when c3 is true, see below)
- bool c3n = !other_one.getFullyConstrained() && getFullyConstrained();
+ // But in no case fall back; (has less priority than c3n, so it is allowed to fall back when c3 is true, see below)
+ bool c3n = !other_one.getFullyConstrained() && getFullyConstrained();
// or, if it's just as close then consider the second distance
- // (which is only relevant for points at an intersection)
- bool c4a = (dist_other == dist_this);
+ bool c4a = (dist_other == dist_this);
bool c4b = other_one.getSecondSnapDistance() < getSecondSnapDistance();
-
+
// std::cout << "c1 = " << c1 << " | c2 = " << c2 << " | c2n = " << c2n << " | c3 = " << c3 << " | c3n = " << c3n << " | c4a = " << c4a << " | c4b = " << c4b << std::endl;
- return (c1 || c2 || c3 || (c4a && c4b)) && !c2n && (!c3n || c2);
+ return (c1 || c2 || c3 || (c4a && c4b)) && !c2n && (!c3n || c2);
}
/*