Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

Inkscape::SnappedPoint SnapManager::findBestSnap ( Inkscape::SnapCandidatePoint const &  p,
SnappedConstraints const &  sc,
bool  constrained,
bool  noCurves = false,
bool  allowOffScreen = false 
) const

Given a set of possible snap targets, find the best target (which is not necessarily also the nearest target), and show the snap indicator if requested.

Parameters:
pSource point to be snapped
scA structure holding all snap targets that have been found so far
constrainedTrue if the snap is constrained, e.g. for stretching or for purely horizontal translation.
noCurvesIf true, then do consider snapping to intersections of curves, but not to the curves themselves
allowOffScreenIf true, then snapping to points which are off the screen is allowed (needed for example when pasting to the grid)
Returns:
An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics

Definition at line 906 of file snap.cpp.

References _snapindicator, and SPDesktop::get_display_area().

Referenced by constrainedSnap(), freeSnap(), guideConstrainedSnap(), guideFreeSnap(), and multipleOfGridPitch().

{


    /*
    std::cout << "Type and number of snapped constraints: " << std::endl;
    std::cout << "  Points      : " << sc.points.size() << std::endl;
    std::cout << "  Lines       : " << sc.lines.size() << std::endl;
    std::cout << "  Grid lines  : " << sc.grid_lines.size()<< std::endl;
    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
    if (!noCurves) {
        Inkscape::SnappedCurve 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.getPoint(), closestCurvesIntersection, _desktop->dt2doc())) {
            closestCurvesIntersection.setSource(p.getSourceType());
            sp_list.push_back(closestCurvesIntersection);
        }
    }

    // search for the closest snapped grid line
    Inkscape::SnappedLine closestGridLine;
    if (getClosestSL(sc.grid_lines, closestGridLine)) {
        sp_list.push_back(Inkscape::SnappedPoint(closestGridLine));
    }

    // search for the closest snapped guide line
    Inkscape::SnappedLine closestGuideLine;
    if (getClosestSL(sc.guide_lines, closestGuideLine)) {
        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

    // 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
    if (!constrained) {
        // search for the closest snapped intersection of grid lines
        Inkscape::SnappedPoint closestGridPoint;
        if (getClosestIntersectionSL(sc.grid_lines, closestGridPoint)) {
            closestGridPoint.setSource(p.getSourceType());
            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.setSource(p.getSourceType());
            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;
            if (getClosestIntersectionSL(sc.grid_lines, sc.guide_lines, closestGridGuidePoint)) {
                closestGridGuidePoint.setSource(p.getSourceType());
                closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
                sp_list.push_back(closestGridGuidePoint);
            }
        }
    }

    // now let's see which snapped point gets a thumbs up
    Inkscape::SnappedPoint bestSnappedPoint(p.getPoint());
    // std::cout << "Finding the best snap..." << std::endl;
    for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
        // std::cout << "sp = " << (*i).getPoint() << " | source = " << (*i).getSource() << " | target = " << (*i).getTarget();
        bool onScreen = _desktop->get_display_area().contains((*i).getPoint());
        if (onScreen || allowOffScreen) { // Only snap to points which are not off the screen
            if ((*i).getSnapDistance() <= (*i).getTolerance()) { // Only snap to points within snapping range
                // 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)) {
                    // 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()) {
            _desktop->snapindicator->set_new_snaptarget(bestSnappedPoint);
        } else {
            _desktop->snapindicator->remove_snaptarget();
        }
    }

    // std::cout << "findBestSnap = " << bestSnappedPoint.getPoint() << " | dist = " << bestSnappedPoint.getSnapDistance() << std::endl;
    return bestSnappedPoint;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index