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