1 #ifndef __2GEOM_REGION_H
2 #define __2GEOM_REGION_H
4 #include <2geom/path.h>
5 #include <2geom/path-intersection.h>
7 namespace Geom {
9 class Shape;
11 class Region {
12 friend Crossings crossings(Region const &a, Region const &b);
13 friend class Shape;
14 friend Shape shape_boolean(bool rev, Shape const & a, Shape const & b, CrossingSet const & crs);
16 Path boundary;
17 mutable boost::optional<Rect> box;
18 bool fill;
19 public:
20 Region() : fill(true) {}
21 explicit Region(Path const &p) : boundary(p) { fill = path_direction(p); }
22 Region(Path const &p, bool dir) : boundary(p), fill(dir) {}
23 Region(Path const &p, boost::optional<Rect> const &b) : boundary(p), box(b) { fill = path_direction(p); }
24 Region(Path const &p, boost::optional<Rect> const &b, bool dir) : boundary(p), box(b), fill(dir) {}
26 unsigned size() const { return boundary.size(); }
28 bool isFill() const { return fill; }
29 Region asFill() const { if(fill) return Region(*this); else return inverse(); }
30 Region asHole() const { if(fill) return inverse(); else return Region(*this); }
32 operator Path() const { return boundary; }
33 Rect boundsFast() const {
34 if(!box) box = boost::optional<Rect>(boundary.boundsFast());
35 return *box;
36 }
38 bool contains(Point const &p) const {
39 if(box && !box->contains(p)) return false;
40 return Geom::contains(boundary, p);
41 }
42 bool contains(Region const &other) const { return contains(other.boundary.initialPoint()); }
44 bool includes(Point const &p) const {
45 return logical_xor(!fill, contains(p));
46 }
48 Region inverse() const { return Region(boundary.reverse(), box, !fill); }
50 Region operator*(Matrix const &m) const;
52 bool invariants() const;
53 };
55 typedef std::vector<Region> Regions;
57 unsigned outer_index(Regions const &ps);
59 //assumes they're already sanitized somewhat
60 inline Regions regions_from_paths(std::vector<Path> const &ps) {
61 Regions res;
62 for(unsigned i = 0; i < ps.size(); i++)
63 res.push_back(Region(ps[i]));
64 return res;
65 }
67 inline std::vector<Path> paths_from_regions(Regions const &rs) {
68 std::vector<Path> res;
69 for(unsigned i = 0; i < rs.size(); i++)
70 res.push_back(rs[i]);
71 return res;
72 }
74 Regions sanitize_path(Path const &p);
76 Regions region_boolean(bool rev, Region const & a, Region const & b, Crossings const &cr);
77 Regions region_boolean(bool rev, Region const & a, Region const & b, Crossings const & cr_a, Crossings const & cr_b);
79 inline Regions region_boolean(bool rev, Region const & a, Region const & b) {
80 return region_boolean(rev, a, b, crossings(a, b));
81 }
83 }
85 #endif
87 /*
88 Local Variables:
89 mode:c++
90 c-file-style:"stroustrup"
91 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
92 indent-tabs-mode:nil
93 fill-column:99
94 End:
95 */
96 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :