1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sdext.hxx"
30 
31 #include "PresenterGeometryHelper.hxx"
32 
33 #include <math.h>
34 #include <algorithm>
35 
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
38 
39 namespace {
40 
41 sal_Int32 Right (const awt::Rectangle& rBox)
42 {
43     return rBox.X + rBox.Width - 1;
44 }
45 
46 sal_Int32 Bottom (const awt::Rectangle& rBox)
47 {
48     return rBox.Y + rBox.Height - 1;
49 }
50 
51 sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight)
52 {
53     return nRight - nLeft + 1;
54 }
55 
56 sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom)
57 {
58     return nBottom - nTop + 1;
59 }
60 
61 
62 } // end of anonymous namespace
63 
64 
65 
66 namespace sdext { namespace presenter {
67 
68 sal_Int32 PresenterGeometryHelper::Floor (const double nValue)
69 {
70     return sal::static_int_cast<sal_Int32>(floor(nValue));
71 }
72 
73 
74 
75 
76 sal_Int32 PresenterGeometryHelper::Ceil (const double nValue)
77 {
78     return sal::static_int_cast<sal_Int32>(ceil(nValue));
79 }
80 
81 
82 
83 
84 sal_Int32 PresenterGeometryHelper::Round (const double nValue)
85 {
86     return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue));
87 }
88 
89 
90 
91 
92 awt::Rectangle PresenterGeometryHelper::ConvertRectangle (
93     const geometry::RealRectangle2D& rBox)
94 {
95     const sal_Int32 nLeft (Floor(rBox.X1));
96     const sal_Int32 nTop (Floor(rBox.Y1));
97     const sal_Int32 nRight (Ceil(rBox.X2));
98     const sal_Int32 nBottom (Ceil(rBox.Y2));
99     return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop);
100 }
101 
102 
103 
104 
105 awt::Rectangle PresenterGeometryHelper::ConvertRectangleWithConstantSize (
106     const geometry::RealRectangle2D& rBox)
107 {
108     return awt::Rectangle (
109         Round(rBox.X1),
110         Round(rBox.Y1),
111         Round(rBox.X2 - rBox.X1),
112         Round(rBox.Y2 - rBox.Y1));
113 }
114 
115 
116 
117 
118 geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle (
119     const css::awt::Rectangle& rBox)
120 {
121     return geometry::RealRectangle2D(
122         rBox.X,
123         rBox.Y,
124         rBox.X + rBox.Width,
125         rBox.Y + rBox.Height);
126 }
127 
128 
129 
130 
131 awt::Rectangle PresenterGeometryHelper::TranslateRectangle (
132     const css::awt::Rectangle& rBox,
133     const sal_Int32 nXOffset,
134     const sal_Int32 nYOffset)
135 {
136     return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height);
137 }
138 
139 
140 
141 
142 awt::Rectangle PresenterGeometryHelper::Intersection (
143     const css::awt::Rectangle& rBox1,
144     const css::awt::Rectangle& rBox2)
145 {
146     const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X));
147     const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y));
148     const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2)));
149     const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2)));
150     if (nLeft >= nRight || nTop >= nBottom)
151         return awt::Rectangle();
152     else
153         return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
154 }
155 
156 
157 
158 
159 geometry::RealRectangle2D PresenterGeometryHelper::Intersection (
160     const geometry::RealRectangle2D& rBox1,
161     const geometry::RealRectangle2D& rBox2)
162 {
163     const double nLeft (::std::max(rBox1.X1, rBox2.X1));
164     const double nTop (::std::max(rBox1.Y1, rBox2.Y1));
165     const double nRight (::std::min(rBox1.X2, rBox2.X2));
166     const double nBottom (::std::min(rBox1.Y2, rBox2.Y2));
167     if (nLeft >= nRight || nTop >= nBottom)
168         return geometry::RealRectangle2D(0,0,0,0);
169     else
170         return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
171 }
172 
173 
174 
175 
176 bool PresenterGeometryHelper::IsInside (
177     const css::geometry::RealRectangle2D& rBox,
178     const css::geometry::RealPoint2D& rPoint)
179 {
180     return rBox.X1 <= rPoint.X
181         && rBox.Y1 <= rPoint.Y
182         && rBox.X2 >= rPoint.X
183         && rBox.Y2 >= rPoint.Y;
184 }
185 
186 
187 
188 
189 bool PresenterGeometryHelper::IsInside (
190     const css::awt::Rectangle& rBox1,
191     const css::awt::Rectangle& rBox2)
192 {
193     return rBox1.X >= rBox2.X
194         && rBox1.Y >= rBox2.Y
195         && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width
196         && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height;
197 }
198 
199 
200 
201 
202 awt::Rectangle PresenterGeometryHelper::Union (
203     const css::awt::Rectangle& rBox1,
204     const css::awt::Rectangle& rBox2)
205 {
206     if (rBox1.Width<=0 || rBox1.Height<=0)
207         return rBox2;
208     else if (rBox2.Width<=0 || rBox2.Height<=0)
209         return rBox1;
210 
211     const sal_Int32 nLeft (::std::min(rBox1.X, rBox2.X));
212     const sal_Int32 nTop (::std::min(rBox1.Y, rBox2.Y));
213     const sal_Int32 nRight (::std::max(Right(rBox1), Right(rBox2)));
214     const sal_Int32 nBottom (::std::max(Bottom(rBox1), Bottom(rBox2)));
215     if (nLeft >= nRight || nTop >= nBottom)
216         return awt::Rectangle();
217     else
218         return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
219 }
220 
221 
222 
223 
224 geometry::RealRectangle2D PresenterGeometryHelper::Union (
225     const geometry::RealRectangle2D& rBox1,
226     const geometry::RealRectangle2D& rBox2)
227 {
228     const double nLeft (::std::min(rBox1.X1, rBox2.X1));
229     const double nTop (::std::min(rBox1.Y1, rBox2.Y1));
230     const double nRight (::std::max(rBox1.X2, rBox2.X2));
231     const double nBottom (::std::max(rBox1.Y2, rBox2.Y2));
232     if (nLeft >= nRight || nTop >= nBottom)
233         return geometry::RealRectangle2D(0,0,0,0);
234     else
235         return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
236 }
237 
238 
239 
240 
241 bool PresenterGeometryHelper::AreRectanglesDisjoint (
242     const css::awt::Rectangle& rBox1,
243     const css::awt::Rectangle& rBox2)
244 {
245     return rBox1.X+rBox1.Width <= rBox2.X
246         || rBox1.Y+rBox1.Height <= rBox2.Y
247         || rBox1.X >= rBox2.X+rBox2.Width
248         || rBox1.Y >= rBox2.Y+rBox2.Height;
249 }
250 
251 
252 
253 
254 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
255     const awt::Rectangle& rBox,
256     const Reference<rendering::XGraphicDevice>& rxDevice)
257 {
258     if ( ! rxDevice.is())
259         return NULL;
260 
261     Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
262     aPoints[0] = Sequence<geometry::RealPoint2D>(4);
263     aPoints[0][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
264     aPoints[0][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
265     aPoints[0][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
266     aPoints[0][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
267     Reference<rendering::XLinePolyPolygon2D> xPolygon (
268         rxDevice->createCompatibleLinePolyPolygon(aPoints));
269     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
270     if (xRectangle.is())
271         xRectangle->setClosed(0, sal_True);
272 
273     return xRectangle;
274 }
275 
276 
277 
278 
279 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
280     const geometry::RealRectangle2D& rBox,
281     const Reference<rendering::XGraphicDevice>& rxDevice)
282 {
283     if ( ! rxDevice.is())
284         return NULL;
285 
286     Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
287     aPoints[0] = Sequence<geometry::RealPoint2D>(4);
288     aPoints[0][0] = geometry::RealPoint2D(rBox.X1, rBox.Y1);
289     aPoints[0][1] = geometry::RealPoint2D(rBox.X1, rBox.Y2);
290     aPoints[0][2] = geometry::RealPoint2D(rBox.X2, rBox.Y2);
291     aPoints[0][3] = geometry::RealPoint2D(rBox.X2, rBox.Y1);
292     Reference<rendering::XLinePolyPolygon2D> xPolygon (
293         rxDevice->createCompatibleLinePolyPolygon(aPoints));
294     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
295     if (xRectangle.is())
296         xRectangle->setClosed(0, sal_True);
297 
298     return xRectangle;
299 }
300 
301 
302 
303 
304 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
305     const ::std::vector<css::awt::Rectangle>& rBoxes,
306     const Reference<rendering::XGraphicDevice>& rxDevice)
307 {
308     if ( ! rxDevice.is())
309         return NULL;
310 
311     const sal_Int32 nCount (rBoxes.size());
312     Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount);
313     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
314     {
315         const awt::Rectangle& rBox (rBoxes[nIndex]);
316         aPoints[nIndex] = Sequence<geometry::RealPoint2D>(4);
317         aPoints[nIndex][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
318         aPoints[nIndex][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
319         aPoints[nIndex][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
320         aPoints[nIndex][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
321     }
322 
323     Reference<rendering::XLinePolyPolygon2D> xPolygon (
324         rxDevice->createCompatibleLinePolyPolygon(aPoints));
325     Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY);
326     if (xRectangle.is())
327         for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
328             xRectangle->setClosed(nIndex, sal_True);
329 
330     return xRectangle;
331 }
332 
333 
334 } }
335