1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _BGFX_RANGE_B2DPOLYRANGE_HXX
25 #define _BGFX_RANGE_B2DPOLYRANGE_HXX
26 
27 #include <o3tl/cow_wrapper.hxx>
28 #include <boost/tuple/tuple.hpp>
29 #include <basegfx/vector/b2enums.hxx>
30 
31 namespace basegfx
32 {
33     class B2DTuple;
34     class B2DRange;
35     class B2DPolyPolygon;
36     class ImplB2DPolyRange;
37 
38     /** Multiple ranges in one object.
39 
40         This class combines multiple ranges in one object, providing a
41         total, enclosing range for it.
42 
43         You can use this class e.g. when updating views containing
44         rectangular objects. Add each modified object to a
45         B2DMultiRange, then test each viewable object against
46         intersection with the multi range.
47 
48         Similar in spirit to the poly-polygon vs. polygon relationship.
49 
50         Note that comparable to polygons, a poly-range can also
51         contain 'holes' - this is encoded via polygon orientation at
52         the poly-polygon, and via explicit flags for the poly-range.
53      */
54     class B2DPolyRange
55     {
56     public:
57         typedef boost::tuple<B2DRange,B2VectorOrientation> ElementType ;
58 
59         B2DPolyRange();
60         ~B2DPolyRange();
61 
62         /** Create a multi range with exactly one containing range
63          */
64         explicit B2DPolyRange( const ElementType& rElement );
65         B2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient );
66         B2DPolyRange( const B2DPolyRange& );
67         B2DPolyRange& operator=( const B2DPolyRange& );
68 
69         /// unshare this poly-range with all internally shared instances
70         void makeUnique();
71 
72         bool operator==(const B2DPolyRange&) const;
73         bool operator!=(const B2DPolyRange&) const;
74 
75         /// Number of included ranges
76         sal_uInt32 count() const;
77 
78         ElementType getElement(sal_uInt32 nIndex) const;
79         void        setElement(sal_uInt32 nIndex, const ElementType& rElement );
80         void        setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient );
81 
82         // insert/append a single range
83         void insertElement(sal_uInt32 nIndex, const ElementType& rElement, sal_uInt32 nCount = 1);
84         void insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1);
85         void appendElement(const ElementType& rElement, sal_uInt32 nCount = 1);
86         void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1);
87 
88         // insert/append multiple ranges
89         void insertPolyRange(sal_uInt32 nIndex, const B2DPolyRange&);
90         void appendPolyRange(const B2DPolyRange&);
91 
92         void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
93         void clear();
94 
95         // flip range orientations - converts holes to solids, and vice versa
96         void flip();
97 
98         /** Get overall range
99 
100             @return
101             The union range of all contained ranges
102         */
103         B2DRange getBounds() const;
104 
105         /** Test whether given tuple is inside one or more of the
106             included ranges. Does *not* use overall range, but checks
107             individually.
108          */
109         bool isInside( const B2DTuple& rTuple ) const;
110 
111         /** Test whether given range is inside one or more of the
112             included ranges. Does *not* use overall range, but checks
113             individually.
114          */
115         bool isInside( const B2DRange& rRange ) const;
116 
117         /** Test whether given range overlaps one or more of the
118             included ranges. Does *not* use overall range, but checks
119             individually.
120          */
121         bool overlaps( const B2DRange& rRange ) const;
122 
123         /** Request a poly-polygon with solved cross-overs
124          */
125         B2DPolyPolygon solveCrossovers() const;
126 
127         // element iterators (same iterator validity conditions as for vector)
128         const B2DRange* begin() const;
129         const B2DRange* end() const;
130         B2DRange* begin();
131         B2DRange* end();
132 
133     private:
134         o3tl::cow_wrapper< ImplB2DPolyRange > mpImpl;
135     };
136 }
137 
138 #endif /* _BGFX_RANGE_B2DPOLYRANGE_HXX */
139