1 #ifndef __2GEOM_REGION_H
2 #define __2GEOM_REGION_H
3 
4 #include "path.h"
5 #include "path-intersection.h"
6 
7 namespace Geom {
8 
9 class Shape;
10 
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);
15 
16     Path boundary;
17     mutable boost::optional<Rect> box;
18     bool fill;
19   public:
Region()20     Region() : fill(true) {}
Region(Path const & p)21     explicit Region(Path const &p) : boundary(p) { fill = path_direction(p); }
Region(Path const & p,bool dir)22     Region(Path const &p, bool dir) : boundary(p), fill(dir) {}
Region(Path const & p,boost::optional<Rect> const & b)23     Region(Path const &p, boost::optional<Rect> const &b) : boundary(p), box(b) { fill = path_direction(p); }
Region(Path const & p,boost::optional<Rect> const & b,bool dir)24     Region(Path const &p, boost::optional<Rect> const &b, bool dir) : boundary(p), box(b), fill(dir) {}
25 
size()26     unsigned size() const { return boundary.size(); }
27 
isFill()28     bool isFill() const { return fill; }
asFill()29     Region asFill() const { if(fill) return Region(*this); else return inverse(); }
asHole()30     Region asHole() const { if(fill) return inverse(); else return Region(*this); }
31 
Path()32     operator Path() const { return boundary; }
boundsFast()33     Rect boundsFast() const {
34         if(!box) box = boost::optional<Rect>(boundary.boundsFast());
35         return *box;
36     }
37 
contains(Point const & p)38     bool contains(Point const &p) const {
39         if(box && !box->contains(p)) return false;
40         return Geom::contains(boundary, p);
41     }
contains(Region const & other)42     bool contains(Region const &other) const { return contains(other.boundary.initialPoint()); }
43 
includes(Point const & p)44     bool includes(Point const &p) const {
45         return logical_xor(!fill, contains(p));
46     }
47 
inverse()48     Region inverse() const { return Region(boundary.reverse(), box, !fill); }
49 
50     Region operator*(Matrix const &m) const;
51 
52     bool invariants() const;
53 };
54 
55 typedef std::vector<Region> Regions;
56 
57 unsigned outer_index(Regions const &ps);
58 
59 //assumes they're already sanitized somewhat
regions_from_paths(std::vector<Path> const & ps)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 }
66 
paths_from_regions(Regions const & rs)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 }
73 
74 Regions sanitize_path(Path const &p);
75 
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);
78 
region_boolean(bool rev,Region const & a,Region const & 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 }
82 
83 }
84 
85 #endif
86