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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26 
27 #include "PresenterGeometryHelper.hxx"
28 
29 #include <math.h>
30 #include <algorithm>
31 
32 using namespace ::com::sun::star;
33 using namespace ::com::sun::star::uno;
34 
35 namespace {
36 
Right(const awt::Rectangle & rBox)37 sal_Int32 Right (const awt::Rectangle& rBox)
38 {
39     return rBox.X + rBox.Width - 1;
40 }
41 
Bottom(const awt::Rectangle & rBox)42 sal_Int32 Bottom (const awt::Rectangle& rBox)
43 {
44     return rBox.Y + rBox.Height - 1;
45 }
46 
Width(const sal_Int32 nLeft,const sal_Int32 nRight)47 sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight)
48 {
49     return nRight - nLeft + 1;
50 }
51 
Height(const sal_Int32 nTop,const sal_Int32 nBottom)52 sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom)
53 {
54     return nBottom - nTop + 1;
55 }
56 
57 
58 } // end of anonymous namespace
59 
60 
61 
62 namespace sdext { namespace presenter {
63 
Floor(const double nValue)64 sal_Int32 PresenterGeometryHelper::Floor (const double nValue)
65 {
66     return sal::static_int_cast<sal_Int32>(floor(nValue));
67 }
68 
69 
70 
71 
Ceil(const double nValue)72 sal_Int32 PresenterGeometryHelper::Ceil (const double nValue)
73 {
74     return sal::static_int_cast<sal_Int32>(ceil(nValue));
75 }
76 
77 
78 
79 
Round(const double nValue)80 sal_Int32 PresenterGeometryHelper::Round (const double nValue)
81 {
82     return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue));
83 }
84 
85 
86 
87 
ConvertRectangle(const geometry::RealRectangle2D & rBox)88 awt::Rectangle PresenterGeometryHelper::ConvertRectangle (
89     const geometry::RealRectangle2D& rBox)
90 {
91     const sal_Int32 nLeft (Floor(rBox.X1));
92     const sal_Int32 nTop (Floor(rBox.Y1));
93     const sal_Int32 nRight (Ceil(rBox.X2));
94     const sal_Int32 nBottom (Ceil(rBox.Y2));
95     return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop);
96 }
97 
98 
99 
100 
ConvertRectangleWithConstantSize(const geometry::RealRectangle2D & rBox)101 awt::Rectangle PresenterGeometryHelper::ConvertRectangleWithConstantSize (
102     const geometry::RealRectangle2D& rBox)
103 {
104     return awt::Rectangle (
105         Round(rBox.X1),
106         Round(rBox.Y1),
107         Round(rBox.X2 - rBox.X1),
108         Round(rBox.Y2 - rBox.Y1));
109 }
110 
111 
112 
113 
ConvertRectangle(const css::awt::Rectangle & rBox)114 geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle (
115     const css::awt::Rectangle& rBox)
116 {
117     return geometry::RealRectangle2D(
118         rBox.X,
119         rBox.Y,
120         rBox.X + rBox.Width,
121         rBox.Y + rBox.Height);
122 }
123 
124 
125 
126 
TranslateRectangle(const css::awt::Rectangle & rBox,const sal_Int32 nXOffset,const sal_Int32 nYOffset)127 awt::Rectangle PresenterGeometryHelper::TranslateRectangle (
128     const css::awt::Rectangle& rBox,
129     const sal_Int32 nXOffset,
130     const sal_Int32 nYOffset)
131 {
132     return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height);
133 }
134 
135 
136 
137 
Intersection(const css::awt::Rectangle & rBox1,const css::awt::Rectangle & rBox2)138 awt::Rectangle PresenterGeometryHelper::Intersection (
139     const css::awt::Rectangle& rBox1,
140     const css::awt::Rectangle& rBox2)
141 {
142     const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X));
143     const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y));
144     const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2)));
145     const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2)));
146     if (nLeft >= nRight || nTop >= nBottom)
147         return awt::Rectangle();
148     else
149         return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
150 }
151 
152 
153 
154 
Intersection(const geometry::RealRectangle2D & rBox1,const geometry::RealRectangle2D & rBox2)155 geometry::RealRectangle2D PresenterGeometryHelper::Intersection (
156     const geometry::RealRectangle2D& rBox1,
157     const geometry::RealRectangle2D& rBox2)
158 {
159     const double nLeft (::std::max(rBox1.X1, rBox2.X1));
160     const double nTop (::std::max(rBox1.Y1, rBox2.Y1));
161     const double nRight (::std::min(rBox1.X2, rBox2.X2));
162     const double nBottom (::std::min(rBox1.Y2, rBox2.Y2));
163     if (nLeft >= nRight || nTop >= nBottom)
164         return geometry::RealRectangle2D(0,0,0,0);
165     else
166         return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
167 }
168 
169 
170 
171 
IsInside(const css::geometry::RealRectangle2D & rBox,const css::geometry::RealPoint2D & rPoint)172 bool PresenterGeometryHelper::IsInside (
173     const css::geometry::RealRectangle2D& rBox,
174     const css::geometry::RealPoint2D& rPoint)
175 {
176     return rBox.X1 <= rPoint.X
177         && rBox.Y1 <= rPoint.Y
178         && rBox.X2 >= rPoint.X
179         && rBox.Y2 >= rPoint.Y;
180 }
181 
182 
183 
184 
IsInside(const css::awt::Rectangle & rBox1,const css::awt::Rectangle & rBox2)185 bool PresenterGeometryHelper::IsInside (
186     const css::awt::Rectangle& rBox1,
187     const css::awt::Rectangle& rBox2)
188 {
189     return rBox1.X >= rBox2.X
190         && rBox1.Y >= rBox2.Y
191         && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width
192         && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height;
193 }
194 
195 
196 
197 
Union(const css::awt::Rectangle & rBox1,const css::awt::Rectangle & rBox2)198 awt::Rectangle PresenterGeometryHelper::Union (
199     const css::awt::Rectangle& rBox1,
200     const css::awt::Rectangle& rBox2)
201 {
202     if (rBox1.Width<=0 || rBox1.Height<=0)
203         return rBox2;
204     else if (rBox2.Width<=0 || rBox2.Height<=0)
205         return rBox1;
206 
207     const sal_Int32 nLeft (::std::min(rBox1.X, rBox2.X));
208     const sal_Int32 nTop (::std::min(rBox1.Y, rBox2.Y));
209     const sal_Int32 nRight (::std::max(Right(rBox1), Right(rBox2)));
210     const sal_Int32 nBottom (::std::max(Bottom(rBox1), Bottom(rBox2)));
211     if (nLeft >= nRight || nTop >= nBottom)
212         return awt::Rectangle();
213     else
214         return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
215 }
216 
217 
218 
219 
Union(const geometry::RealRectangle2D & rBox1,const geometry::RealRectangle2D & rBox2)220 geometry::RealRectangle2D PresenterGeometryHelper::Union (
221     const geometry::RealRectangle2D& rBox1,
222     const geometry::RealRectangle2D& rBox2)
223 {
224     const double nLeft (::std::min(rBox1.X1, rBox2.X1));
225     const double nTop (::std::min(rBox1.Y1, rBox2.Y1));
226     const double nRight (::std::max(rBox1.X2, rBox2.X2));
227     const double nBottom (::std::max(rBox1.Y2, rBox2.Y2));
228     if (nLeft >= nRight || nTop >= nBottom)
229         return geometry::RealRectangle2D(0,0,0,0);
230     else
231         return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
232 }
233 
234 
235 
236 
AreRectanglesDisjoint(const css::awt::Rectangle & rBox1,const css::awt::Rectangle & rBox2)237 bool PresenterGeometryHelper::AreRectanglesDisjoint (
238     const css::awt::Rectangle& rBox1,
239     const css::awt::Rectangle& rBox2)
240 {
241     return rBox1.X+rBox1.Width <= rBox2.X
242         || rBox1.Y+rBox1.Height <= rBox2.Y
243         || rBox1.X >= rBox2.X+rBox2.Width
244         || rBox1.Y >= rBox2.Y+rBox2.Height;
245 }
246 
247 
248 
249 
CreatePolygon(const awt::Rectangle & rBox,const Reference<rendering::XGraphicDevice> & rxDevice)250 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
251     const awt::Rectangle& rBox,
252     const Reference<rendering::XGraphicDevice>& rxDevice)
253 {
254     if ( ! rxDevice.is())
255         return NULL;
256 
257     Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
258     aPoints[0] = Sequence<geometry::RealPoint2D>(4);
259     aPoints[0][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
260     aPoints[0][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
261     aPoints[0][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
262     aPoints[0][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
263     Reference<rendering::XLinePolyPolygon2D> xPolygon (
264         rxDevice->createCompatibleLinePolyPolygon(aPoints));
265     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
266     if (xRectangle.is())
267         xRectangle->setClosed(0, sal_True);
268 
269     return xRectangle;
270 }
271 
272 
273 
274 
CreatePolygon(const geometry::RealRectangle2D & rBox,const Reference<rendering::XGraphicDevice> & rxDevice)275 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
276     const geometry::RealRectangle2D& rBox,
277     const Reference<rendering::XGraphicDevice>& rxDevice)
278 {
279     if ( ! rxDevice.is())
280         return NULL;
281 
282     Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
283     aPoints[0] = Sequence<geometry::RealPoint2D>(4);
284     aPoints[0][0] = geometry::RealPoint2D(rBox.X1, rBox.Y1);
285     aPoints[0][1] = geometry::RealPoint2D(rBox.X1, rBox.Y2);
286     aPoints[0][2] = geometry::RealPoint2D(rBox.X2, rBox.Y2);
287     aPoints[0][3] = geometry::RealPoint2D(rBox.X2, rBox.Y1);
288     Reference<rendering::XLinePolyPolygon2D> xPolygon (
289         rxDevice->createCompatibleLinePolyPolygon(aPoints));
290     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
291     if (xRectangle.is())
292         xRectangle->setClosed(0, sal_True);
293 
294     return xRectangle;
295 }
296 
297 
298 
299 
CreatePolygon(const::std::vector<css::awt::Rectangle> & rBoxes,const Reference<rendering::XGraphicDevice> & rxDevice)300 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
301     const ::std::vector<css::awt::Rectangle>& rBoxes,
302     const Reference<rendering::XGraphicDevice>& rxDevice)
303 {
304     if ( ! rxDevice.is())
305         return NULL;
306 
307     const sal_Int32 nCount (rBoxes.size());
308     Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount);
309     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
310     {
311         const awt::Rectangle& rBox (rBoxes[nIndex]);
312         aPoints[nIndex] = Sequence<geometry::RealPoint2D>(4);
313         aPoints[nIndex][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
314         aPoints[nIndex][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
315         aPoints[nIndex][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
316         aPoints[nIndex][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
317     }
318 
319     Reference<rendering::XLinePolyPolygon2D> xPolygon (
320         rxDevice->createCompatibleLinePolyPolygon(aPoints));
321     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
322     if (xRectangle.is())
323         for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
324             xRectangle->setClosed(nIndex, sal_True);
325 
326     return xRectangle;
327 }
328 
329 
330 } }
331