~inkscape.dev/inkscape/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef SEEN_OBJECT_SNAPPER_H
#define SEEN_OBJECT_SNAPPER_H
/*
 * Authors:
 *   Carl Hetherington <inkscape@carlh.net>
 *   Diederik van Lierop <mail@diedenrezi.nl>
 *
 * Copyright (C) 2005 - 2011 Authors
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#include "snapper.h"
#include "sp-path.h"
#include "splivarot.h"
#include "snap-candidate.h"

class SPNamedView;
class  SPItem;
class  SPObject;

namespace Inkscape
{

/**
 * Snapping things to objects.
 */
class ObjectSnapper : public Snapper
{

public:
    ObjectSnapper(SnapManager *sm, Geom::Coord const d);
    ~ObjectSnapper();

    /**
     * @return true if this Snapper will snap at least one kind of point.
     */
    bool ThisSnapperMightSnap() const;

    /**
     * @return Snap tolerance (desktop coordinates); depends on current zoom so that it's always the same in screen pixels.
     */
    Geom::Coord getSnapperTolerance() const; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom)

    bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance

    void freeSnap(IntermSnapResults &isr,
                  Inkscape::SnapCandidatePoint const &p,
                  Geom::OptRect const &bbox_to_snap,
                  std::vector<SPItem const *> const *it,
                  std::vector<SnapCandidatePoint> *unselected_nodes) const;

    void constrainedSnap(IntermSnapResults &isr,
                  Inkscape::SnapCandidatePoint const &p,
                  Geom::OptRect const &bbox_to_snap,
                  SnapConstraint const &c,
                  std::vector<SPItem const *> const *it,
                  std::vector<SnapCandidatePoint> *unselected_nodes) const;

private:
    //store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap
    std::vector<SnapCandidateItem> *_candidates;
    std::vector<SnapCandidatePoint> *_points_to_snap_to;
    std::vector<SnapCandidatePath > *_paths_to_snap_to;

    /**
     * Find all items within snapping range.
     * @param parent Pointer to the document's root, or to a clipped path or mask object.
     * @param it List of items to ignore.
     * @param bbox_to_snap Bounding box hulling the whole bunch of points, all from the same selection and having the same transformation.
     * @param clip_or_mask The parent object being passed is either a clip or mask.
     */
    void _findCandidates(SPObject* parent,
                       std::vector<SPItem const *> const *it,
                       bool const &first_point,
                       Geom::Rect const &bbox_to_snap,
                       bool const _clip_or_mask,
                       Geom::Affine const additional_affine) const;

    void _snapNodes(IntermSnapResults &isr,
                      Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
                      std::vector<SnapCandidatePoint> *unselected_nodes,
                      SnapConstraint const &c = SnapConstraint(),
                      Geom::Point const &p_proj_on_constraint = Geom::Point()) const;

    void _snapTranslatingGuide(IntermSnapResults &isr,
                     Geom::Point const &p,
                     Geom::Point const &guide_normal) const;

    void _collectNodes(Inkscape::SnapSourceType const &t,
                  bool const &first_point) const;

    void _snapPaths(IntermSnapResults &isr,
                      Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
                      std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes, // in desktop coordinates
                      SPPath const *selected_path) const;

    void _snapPathsConstrained(IntermSnapResults &isr,
                 Inkscape::SnapCandidatePoint const &p, // in desktop coordinates
                 SnapConstraint const &c,
                 Geom::Point const &p_proj_on_constraint) const;

    void _snapPathsTangPerp(bool snap_tang,
                            bool snap_perp,
                            IntermSnapResults &isr,
                            SnapCandidatePoint const &p,
                            Geom::Curve const *curve,
                            SPDesktop const *dt) const;

    bool isUnselectedNode(Geom::Point const &point, std::vector<Inkscape::SnapCandidatePoint> const *unselected_nodes) const;

    /**
     * Returns index of first NR_END bpath in array.
     */
    void _collectPaths(Geom::Point p,
                      Inkscape::SnapSourceType const source_type,
                      bool const &first_point) const;

    void _clear_paths() const;
    Geom::PathVector* _getBorderPathv() const;
    Geom::PathVector* _getPathvFromRect(Geom::Rect const rect) const;
    void _getBorderNodes(std::vector<SnapCandidatePoint> *points) const;
    bool _allowSourceToSnapToTarget(SnapSourceType source, SnapTargetType target, bool strict_snapping) const;

}; // end of ObjectSnapper class

void getBBoxPoints(Geom::OptRect const bbox, std::vector<SnapCandidatePoint> *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);

} // end of namespace Inkscape

#endif