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_basegfx.hxx"
26 
27 #include <com/sun/star/geometry/RealSize2D.hpp>
28 #include <com/sun/star/geometry/RealPoint2D.hpp>
29 #include <com/sun/star/geometry/RealRectangle2D.hpp>
30 #include <com/sun/star/geometry/RealRectangle3D.hpp>
31 #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
32 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
33 #include <com/sun/star/geometry/AffineMatrix3D.hpp>
34 #include <com/sun/star/geometry/Matrix2D.hpp>
35 #include <com/sun/star/geometry/IntegerSize2D.hpp>
36 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
37 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
38 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
39 #include <com/sun/star/rendering/XGraphicDevice.hpp>
40 #include <com/sun/star/awt/Size.hpp>
41 #include <com/sun/star/awt/Point.hpp>
42 #include <com/sun/star/awt/Rectangle.hpp>
43 #include <basegfx/tools/unopolypolygon.hxx>
44 #include <basegfx/matrix/b2dhommatrix.hxx>
45 #include <basegfx/matrix/b3dhommatrix.hxx>
46 #include <basegfx/vector/b2dsize.hxx>
47 #include <basegfx/point/b2dpoint.hxx>
48 #include <basegfx/range/b2drectangle.hxx>
49 #include <basegfx/range/b3drange.hxx>
50 #include <basegfx/vector/b2isize.hxx>
51 #include <basegfx/point/b2ipoint.hxx>
52 #include <basegfx/range/b2irectangle.hxx>
53 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <basegfx/polygon/b2dpolypolygon.hxx>
55 #include <basegfx/tools/canvastools.hxx>
56 #include <limits>
57 
58 using namespace ::com::sun::star;
59 
60 namespace basegfx
61 {
62 
63     namespace unotools
64     {
65         namespace
66         {
67             uno::Sequence< geometry::RealBezierSegment2D > bezierSequenceFromB2DPolygon(const ::basegfx::B2DPolygon& rPoly)
68             {
69                 const sal_uInt32 nPointCount(rPoly.count());
70                 uno::Sequence< geometry::RealBezierSegment2D > outputSequence(nPointCount);
71                 geometry::RealBezierSegment2D* pOutput = outputSequence.getArray();
72 
73 				// fill sequences and imply clodes polygon on this implementation layer
74 				for(sal_uInt32 a(0); a < nPointCount; a++)
75 				{
76                     const basegfx::B2DPoint aStart(rPoly.getB2DPoint(a));
77                     const basegfx::B2DPoint aControlA(rPoly.getNextControlPoint(a));
78                     const basegfx::B2DPoint aControlB(rPoly.getPrevControlPoint((a + 1) % nPointCount));
79 
80 					pOutput[a] = geometry::RealBezierSegment2D(
81 						aStart.getX(), aStart.getY(),
82 						aControlA.getX(), aControlA.getY(),
83 						aControlB.getX(), aControlB.getY());
84 				}
85 
86                 return outputSequence;
87             }
88 
89             uno::Sequence< geometry::RealPoint2D > pointSequenceFromB2DPolygon( const ::basegfx::B2DPolygon& rPoly )
90             {
91                 const sal_uInt32 nNumPoints( rPoly.count() );
92 
93                 uno::Sequence< geometry::RealPoint2D > outputSequence( nNumPoints );
94                 geometry::RealPoint2D* pOutput = outputSequence.getArray();
95 
96                 // fill sequence from polygon
97                 sal_uInt32 i;
98                 for( i=0; i<nNumPoints; ++i )
99                 {
100                     const ::basegfx::B2DPoint 	aPoint( rPoly.getB2DPoint(i) );
101 
102                     pOutput[i] = geometry::RealPoint2D( aPoint.getX(),
103                                                         aPoint.getY() );
104                 }
105 
106                 return outputSequence;
107             }
108         }
109 
110         //---------------------------------------------------------------------------------------
111 
112         uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > > bezierSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly )
113         {
114             const sal_uInt32 nNumPolies( rPolyPoly.count() );
115             sal_uInt32 i;
116 
117             uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > > outputSequence( nNumPolies );
118             uno::Sequence< geometry::RealBezierSegment2D >* pOutput = outputSequence.getArray();
119 
120             for( i=0; i<nNumPolies; ++i )
121             {
122                 pOutput[i] = bezierSequenceFromB2DPolygon( rPolyPoly.getB2DPolygon(i) );
123             }
124 
125             return outputSequence;
126         }
127 
128         //---------------------------------------------------------------------------------------
129 
130         uno::Sequence< uno::Sequence< geometry::RealPoint2D > > pointSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly	 )
131         {
132             const sal_uInt32 nNumPolies( rPolyPoly.count() );
133             sal_uInt32 i;
134 
135             uno::Sequence< uno::Sequence< geometry::RealPoint2D > > outputSequence( nNumPolies );
136             uno::Sequence< geometry::RealPoint2D >* pOutput = outputSequence.getArray();
137 
138             for( i=0; i<nNumPolies; ++i )
139             {
140                 pOutput[i] = pointSequenceFromB2DPolygon( rPolyPoly.getB2DPolygon(i) );
141             }
142 
143             return outputSequence;
144         }
145 
146         //---------------------------------------------------------------------------------------
147 
148         uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromB2DPolygon( const uno::Reference< rendering::XGraphicDevice >& 	xGraphicDevice,
149                                                                                 const ::basegfx::B2DPolygon&						rPoly	 )
150         {
151             uno::Reference< rendering::XPolyPolygon2D > xRes;
152 
153             if( !xGraphicDevice.is() )
154                 return xRes;
155 
156             if( rPoly.areControlPointsUsed() )
157             {
158                 uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > > outputSequence( 1 );
159                 outputSequence[0] = bezierSequenceFromB2DPolygon( rPoly );
160 
161                 xRes.set( xGraphicDevice->createCompatibleBezierPolyPolygon( outputSequence ),
162                           uno::UNO_QUERY );
163             }
164             else
165             {
166                 uno::Sequence< uno::Sequence< geometry::RealPoint2D > > outputSequence( 1 );
167                 outputSequence[0] = pointSequenceFromB2DPolygon( rPoly );
168 
169                 xRes.set( xGraphicDevice->createCompatibleLinePolyPolygon( outputSequence ),
170                           uno::UNO_QUERY );
171             }
172 
173             if( xRes.is() && rPoly.isClosed() )
174                 xRes->setClosed( 0, sal_True );
175 
176             return xRes;
177         }
178 
179         //---------------------------------------------------------------------------------------
180 
181         uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromB2DPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& 	xGraphicDevice,
182                                                                                     const ::basegfx::B2DPolyPolygon&					rPolyPoly	 )
183         {
184             uno::Reference< rendering::XPolyPolygon2D > xRes;
185 
186             if( !xGraphicDevice.is() )
187                 return xRes;
188 
189             const sal_uInt32 nNumPolies( rPolyPoly.count() );
190             sal_uInt32 i;
191 
192             if( rPolyPoly.areControlPointsUsed() )
193             {
194                 xRes.set( xGraphicDevice->createCompatibleBezierPolyPolygon(
195                               bezierSequenceSequenceFromB2DPolyPolygon( rPolyPoly ) ),
196                           uno::UNO_QUERY );
197             }
198             else
199             {
200                 xRes.set( xGraphicDevice->createCompatibleLinePolyPolygon(
201                               pointSequenceSequenceFromB2DPolyPolygon( rPolyPoly ) ),
202                           uno::UNO_QUERY );
203             }
204 
205             for( i=0; i<nNumPolies; ++i )
206             {
207 	            xRes->setClosed( i, rPolyPoly.getB2DPolygon(i).isClosed() );
208             }
209 
210             return xRes;
211         }
212 
213         //---------------------------------------------------------------------------------------
214 
215         ::basegfx::B2DPolygon polygonFromPoint2DSequence( const uno::Sequence< geometry::RealPoint2D >& points )
216         {
217             const sal_Int32 nCurrSize( points.getLength() );
218 
219             ::basegfx::B2DPolygon aPoly;
220 
221             for( sal_Int32 nCurrPoint=0; nCurrPoint<nCurrSize; ++nCurrPoint )
222                 aPoly.append( b2DPointFromRealPoint2D( points[nCurrPoint] ) );
223 
224             return aPoly;
225         }
226 
227         //---------------------------------------------------------------------------------------
228 
229         ::basegfx::B2DPolyPolygon polyPolygonFromPoint2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
230         {
231             ::basegfx::B2DPolyPolygon aRes;
232 
233             for( sal_Int32 nCurrPoly=0; nCurrPoly<points.getLength(); ++nCurrPoly )
234             {
235                 aRes.append( polygonFromPoint2DSequence( points[nCurrPoly] ) );
236             }
237 
238             return aRes;
239         }
240 
241         //---------------------------------------------------------------------------------------
242 
243         ::basegfx::B2DPolygon polygonFromBezier2DSequence( const uno::Sequence< geometry::RealBezierSegment2D >& curves )
244         {
245             const sal_Int32 nSize(curves.getLength());
246 			basegfx::B2DPolygon aRetval;
247 
248 			if(nSize)
249 			{
250 				// prepare start with providing a start point. Use the first point from
251 				// the sequence for this
252 				const geometry::RealBezierSegment2D& rFirstSegment(curves[0]); // #i79917# first segment, not last
253 				aRetval.append(basegfx::B2DPoint(rFirstSegment.Px, rFirstSegment.Py));
254 
255 				for(sal_Int32 a(0); a < nSize; a++)
256 				{
257 					const geometry::RealBezierSegment2D& rCurrSegment(curves[a]);
258 					const geometry::RealBezierSegment2D& rNextSegment(curves[(a + 1) % nSize]);
259 
260 					// append curved edge with the control points and the next point
261 					aRetval.appendBezierSegment(
262 						basegfx::B2DPoint(rCurrSegment.C1x, rCurrSegment.C1y),
263 						basegfx::B2DPoint(rCurrSegment.C2x, rCurrSegment.C2y), // #i79917# Argh! An x for an y!!
264 						basegfx::B2DPoint(rNextSegment.Px, rNextSegment.Py));
265 				}
266 
267 				// rescue the control point and remove the now double-added point
268 				aRetval.setPrevControlPoint(0, aRetval.getPrevControlPoint(aRetval.count() - 1));
269 				aRetval.remove(aRetval.count() - 1);
270 			}
271 
272 			return aRetval;
273         }
274 
275         //---------------------------------------------------------------------------------------
276 
277         ::basegfx::B2DPolyPolygon polyPolygonFromBezier2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& curves )
278         {
279             ::basegfx::B2DPolyPolygon aRes;
280 
281             for( sal_Int32 nCurrPoly=0; nCurrPoly<curves.getLength(); ++nCurrPoly )
282             {
283                 aRes.append( polygonFromBezier2DSequence( curves[nCurrPoly] ) );
284             }
285 
286             return aRes;
287         }
288 
289         //---------------------------------------------------------------------------------------
290 
291         ::basegfx::B2DPolyPolygon b2DPolyPolygonFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
292         {
293             ::basegfx::unotools::UnoPolyPolygon* pPolyImpl =
294                 dynamic_cast< ::basegfx::unotools::UnoPolyPolygon* >( xPoly.get() );
295 
296             if( pPolyImpl )
297             {
298                 return pPolyImpl->getPolyPolygon();
299             }
300             else
301             {
302                 // not a known implementation object - try data source
303                 // interfaces
304                 const sal_Int32 nPolys( xPoly->getNumberOfPolygons() );
305 
306                 uno::Reference< rendering::XBezierPolyPolygon2D > xBezierPoly(
307                     xPoly,
308                     uno::UNO_QUERY );
309 
310                 if( xBezierPoly.is() )
311                 {
312                     return ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(
313                         xBezierPoly->getBezierSegments( 0,
314                                                         nPolys,
315                                                         0,
316                                                         -1 ) );
317                 }
318                 else
319                 {
320                     uno::Reference< rendering::XLinePolyPolygon2D > xLinePoly(
321                         xPoly,
322                         uno::UNO_QUERY );
323 
324                     // no implementation class and no data provider
325                     // found - contract violation.
326                     if( !xLinePoly.is() )
327                     {
328                         throw lang::IllegalArgumentException(
329                             ::rtl::OUString::createFromAscii(
330                                     "basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(): Invalid input"
331                                     "poly-polygon, cannot retrieve vertex data"),
332                             uno::Reference< uno::XInterface >(),
333                             0 );
334                     }
335 
336                     return ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence(
337                         xLinePoly->getPoints( 0,
338                                               nPolys,
339                                               0,
340                                               -1 ));
341                 }
342             }
343         }
344 
345         //---------------------------------------------------------------------------------------
346 
347         ::basegfx::B2DHomMatrix& homMatrixFromAffineMatrix( ::basegfx::B2DHomMatrix&		output,
348                                                             const geometry::AffineMatrix2D&	input )
349         {
350             // ensure last row is [0,0,1] (and optimized away)
351             output.identity();
352 
353             output.set(0,0, input.m00);
354             output.set(0,1, input.m01);
355             output.set(0,2, input.m02);
356             output.set(1,0, input.m10);
357             output.set(1,1, input.m11);
358             output.set(1,2, input.m12);
359 
360             return output;
361         }
362 
363         ::basegfx::B2DHomMatrix homMatrixFromAffineMatrix( const geometry::AffineMatrix2D& input )
364         {
365             ::basegfx::B2DHomMatrix output;
366 
367             output.set(0,0, input.m00);
368             output.set(0,1, input.m01);
369             output.set(0,2, input.m02);
370             output.set(1,0, input.m10);
371             output.set(1,1, input.m11);
372             output.set(1,2, input.m12);
373 
374             return output;
375         }
376 
377 		::basegfx::B3DHomMatrix homMatrixFromAffineMatrix3D( const ::com::sun::star::geometry::AffineMatrix3D& input )
378 		{
379             ::basegfx::B3DHomMatrix output;
380 
381             output.set(0,0, input.m00);
382             output.set(0,1, input.m01);
383             output.set(0,2, input.m02);
384             output.set(0,3, input.m03);
385 
386             output.set(1,0, input.m10);
387             output.set(1,1, input.m11);
388             output.set(1,2, input.m12);
389             output.set(1,3, input.m13);
390 
391             output.set(2,0, input.m20);
392             output.set(2,1, input.m21);
393             output.set(2,2, input.m22);
394             output.set(2,3, input.m23);
395 
396             return output;
397 		}
398 
399         geometry::AffineMatrix2D& affineMatrixFromHomMatrix( geometry::AffineMatrix2D&		output,
400                                                              const ::basegfx::B2DHomMatrix&	input)
401         {
402             output.m00 = input.get(0,0);
403             output.m01 = input.get(0,1);
404             output.m02 = input.get(0,2);
405             output.m10 = input.get(1,0);
406             output.m11 = input.get(1,1);
407             output.m12 = input.get(1,2);
408 
409             return output;
410         }
411 
412         geometry::AffineMatrix3D& affineMatrixFromHomMatrix3D(
413 			geometry::AffineMatrix3D& output,
414 			const ::basegfx::B3DHomMatrix&	input)
415         {
416             output.m00 = input.get(0,0);
417             output.m01 = input.get(0,1);
418             output.m02 = input.get(0,2);
419             output.m03 = input.get(0,3);
420 
421 			output.m10 = input.get(1,0);
422             output.m11 = input.get(1,1);
423             output.m12 = input.get(1,2);
424             output.m13 = input.get(1,3);
425 
426 			output.m20 = input.get(2,0);
427             output.m21 = input.get(2,1);
428             output.m22 = input.get(2,2);
429             output.m23 = input.get(2,3);
430 
431             return output;
432         }
433 
434         //---------------------------------------------------------------------------------------
435 
436         ::basegfx::B2DHomMatrix& homMatrixFromMatrix( ::basegfx::B2DHomMatrix&	output,
437                                                       const geometry::Matrix2D& input )
438         {
439             // ensure last row is [0,0,1] (and optimized away)
440             output.identity();
441 
442             output.set(0,0, input.m00);
443             output.set(0,1, input.m01);
444             output.set(1,0, input.m10);
445             output.set(1,1, input.m11);
446 
447             return output;
448         }
449 
450         //---------------------------------------------------------------------------------------
451 
452         geometry::RealSize2D size2DFromB2DSize( const ::basegfx::B2DVector& rVec )
453         {
454             return geometry::RealSize2D( rVec.getX(),
455                                          rVec.getY() );
456         }
457 
458         geometry::RealPoint2D point2DFromB2DPoint( const ::basegfx::B2DPoint& rPoint )
459         {
460             return geometry::RealPoint2D( rPoint.getX(),
461                                           rPoint.getY() );
462         }
463 
464         geometry::RealRectangle2D rectangle2DFromB2DRectangle( const ::basegfx::B2DRange& rRect )
465         {
466             return geometry::RealRectangle2D( rRect.getMinX(),
467                                               rRect.getMinY(),
468                                               rRect.getMaxX(),
469                                               rRect.getMaxY() );
470         }
471 
472         geometry::RealRectangle3D rectangle3DFromB3DRectangle( const ::basegfx::B3DRange& rRect )
473         {
474             return geometry::RealRectangle3D( rRect.getMinX(),
475                                               rRect.getMinY(),
476                                               rRect.getMinZ(),
477                                               rRect.getMaxX(),
478                                               rRect.getMaxY(),
479 											  rRect.getMaxZ());
480         }
481 
482         ::basegfx::B2DVector b2DSizeFromRealSize2D( const geometry::RealSize2D& rSize )
483         {
484             return ::basegfx::B2DVector( rSize.Width,
485                                          rSize.Height );
486         }
487 
488         ::basegfx::B2DPoint b2DPointFromRealPoint2D( const geometry::RealPoint2D& rPoint )
489         {
490             return ::basegfx::B2DPoint( rPoint.X,
491                                         rPoint.Y );
492         }
493 
494         ::basegfx::B2DRange b2DRectangleFromRealRectangle2D( const geometry::RealRectangle2D& rRect )
495         {
496             return ::basegfx::B2DRange( rRect.X1,
497                                         rRect.Y1,
498                                         rRect.X2,
499                                         rRect.Y2 );
500         }
501 
502         ::basegfx::B3DRange b3DRectangleFromRealRectangle3D( const geometry::RealRectangle3D& rRect )
503         {
504             return ::basegfx::B3DRange( rRect.X1,
505                                         rRect.Y1,
506                                         rRect.Z1,
507                                         rRect.X2,
508                                         rRect.Y2,
509 										rRect.Z2);
510         }
511 
512         geometry::IntegerSize2D integerSize2DFromB2ISize( const ::basegfx::B2IVector& rSize )
513         {
514             return geometry::IntegerSize2D( rSize.getX(),
515                                             rSize.getY() );
516         }
517 
518         geometry::IntegerPoint2D integerPoint2DFromB2IPoint( const ::basegfx::B2IPoint& rPoint )
519         {
520             return geometry::IntegerPoint2D( rPoint.getX(),
521                                              rPoint.getY() );
522         }
523 
524         geometry::IntegerRectangle2D integerRectangle2DFromB2IRectangle( const ::basegfx::B2IRange& rRectangle )
525         {
526             return geometry::IntegerRectangle2D( rRectangle.getMinX(), rRectangle.getMinY(),
527                                                  rRectangle.getMaxX(), rRectangle.getMaxY() );
528         }
529 
530         ::basegfx::B2IVector b2ISizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
531         {
532             return ::basegfx::B2IVector( rSize.Width,
533                                          rSize.Height );
534         }
535 
536         ::basegfx::B2IPoint b2IPointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint )
537         {
538             return ::basegfx::B2IPoint( rPoint.X,
539                                         rPoint.Y );
540         }
541 
542         ::basegfx::B2IRange b2IRectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
543         {
544             return ::basegfx::B2IRange( rRectangle.X1, rRectangle.Y1,
545                                         rRectangle.X2, rRectangle.Y2 );
546         }
547 
548         awt::Size awtSizeFromB2ISize( const ::basegfx::B2IVector& rVec )
549         {
550             return awt::Size( rVec.getX(),
551                               rVec.getY() );
552         }
553 
554         awt::Point awtPointFromB2IPoint( const ::basegfx::B2IPoint& rPoint )
555         {
556             return awt::Point( rPoint.getX(),
557                                rPoint.getY() );
558         }
559 
560         awt::Rectangle awtRectangleFromB2IRectangle( const ::basegfx::B2IRange& rRect )
561         {
562             OSL_ENSURE( rRect.getWidth() < ::std::numeric_limits< sal_Int32 >::max() &&
563                         rRect.getWidth() > ::std::numeric_limits< sal_Int32 >::min(),
564                         "awtRectangleFromB2IRectangle(): width overflow" );
565             OSL_ENSURE( rRect.getHeight() < ::std::numeric_limits< sal_Int32 >::max() &&
566                         rRect.getHeight() > ::std::numeric_limits< sal_Int32 >::min(),
567                         "awtRectangleFromB2IRectangle(): height overflow" );
568 
569             return awt::Rectangle( rRect.getMinX(),
570                                    rRect.getMinY(),
571                                    static_cast< sal_Int32 >(rRect.getWidth()),
572                                    static_cast< sal_Int32 >(rRect.getHeight()) );
573         }
574 
575         ::basegfx::B2IVector b2ISizeFromAwtSize( const awt::Size& rSize )
576         {
577             return ::basegfx::B2IVector( rSize.Width,
578                                          rSize.Height );
579         }
580 
581         ::basegfx::B2IPoint b2IPointFromAwtPoint( const awt::Point& rPoint )
582         {
583             return ::basegfx::B2IPoint( rPoint.X,
584                                         rPoint.Y );
585         }
586 
587         ::basegfx::B2IRange b2IRectangleFromAwtRectangle( const awt::Rectangle& rRect )
588         {
589             return ::basegfx::B2IRange( rRect.X,
590                                         rRect.Y,
591                                         rRect.X + rRect.Width,
592                                         rRect.Y + rRect.Height );
593         }
594 
595         ::basegfx::B2IRange b2ISurroundingRangeFromB2DRange( const ::basegfx::B2DRange& rRange )
596         {
597             return ::basegfx::B2IRange( static_cast<sal_Int32>( floor(rRange.getMinX()) ),
598                                         static_cast<sal_Int32>( floor(rRange.getMinY()) ),
599                                         static_cast<sal_Int32>( ceil(rRange.getMaxX()) ),
600                                         static_cast<sal_Int32>( ceil(rRange.getMaxY()) ) );
601         }
602 
603         ::basegfx::B2DRange b2DSurroundingIntegerRangeFromB2DRange( const ::basegfx::B2DRange& rRange )
604         {
605             return ::basegfx::B2DRange( floor(rRange.getMinX()),
606                                         floor(rRange.getMinY()),
607                                         ceil(rRange.getMaxX()),
608                                         ceil(rRange.getMaxY()) );
609         }
610 
611         // Geometry comparisons
612         // ===================================================================
613 
614 		bool RealSize2DAreEqual( const ::com::sun::star::geometry::RealSize2D& rA, const ::com::sun::star::geometry::RealSize2D& rB )
615 		{
616 			return (rA.Width == rB.Width && rA.Height == rB.Height);
617 		}
618 
619 		bool RealPoint2DAreEqual( const ::com::sun::star::geometry::RealPoint2D& rA, const ::com::sun::star::geometry::RealPoint2D& rB )
620 		{
621 			return (rA.X == rB.X && rA.Y == rB.Y);
622 		}
623 
624 		bool RealRectangle2DAreEqual( const ::com::sun::star::geometry::RealRectangle2D& rA, const ::com::sun::star::geometry::RealRectangle2D& rB )
625 		{
626 			return (rA.X1 == rB.X1 && rA.Y1 == rB.Y1 && rA.X2 == rB.X2 && rA.Y2 == rB.Y2);
627 		}
628 
629 		bool RealRectangle3DAreEqual( const ::com::sun::star::geometry::RealRectangle3D& rA, const ::com::sun::star::geometry::RealRectangle3D& rB )
630 		{
631 			return (rA.X1 == rB.X1 && rA.Y1 == rB.Y1 && rA.Z1 == rB.Z1 && rA.X2 == rB.X2 && rA.Y2 == rB.Y2 && rA.Z2 == rB.Z2);
632 		}
633 
634 		bool AffineMatrix2DAreEqual( const ::com::sun::star::geometry::AffineMatrix2D& rA, const ::com::sun::star::geometry::AffineMatrix2D& rB )
635 		{
636 			return (rA.m00 == rB.m00 && rA.m01 == rB.m01 && rA.m02 == rB.m02 && rA.m10 == rB.m10 && rA.m11 == rB.m11 && rA.m12 == rB.m12);
637 		}
638 
639 		bool IntegerSize2DAreEqual( const ::com::sun::star::geometry::IntegerSize2D& rA, const ::com::sun::star::geometry::IntegerSize2D& rB )
640 		{
641 			return (rA.Width == rB.Width && rA.Height == rB.Height);
642 		}
643 
644 		bool IntegerPoint2DAreEqual( const ::com::sun::star::geometry::IntegerPoint2D& rA, const ::com::sun::star::geometry::IntegerPoint2D& rB )
645 		{
646 			return (rA.X == rB.X && rA.Y == rB.Y);
647 		}
648 
649 		bool IntegerRectangle2DAreEqual( const ::com::sun::star::geometry::IntegerRectangle2D& rA, const ::com::sun::star::geometry::IntegerRectangle2D& rB )
650 		{
651 			return (rA.X1 == rB.X1 && rA.Y1 == rB.Y1 && rA.X2 == rB.X2 && rA.Y2 == rB.Y2);
652 		}
653 
654 		bool awtSizeAreEqual( const ::com::sun::star::awt::Size& rA, const ::com::sun::star::awt::Size& rB )
655 		{
656 			return (rA.Width == rB.Width && rA.Height == rB.Height);
657 		}
658 
659 		bool awtPointAreEqual( const ::com::sun::star::awt::Point& rA, const ::com::sun::star::awt::Point& rB )
660 		{
661 			return (rA.X == rB.X && rA.Y == rB.Y);
662 		}
663 
664 		bool awtRectangleAreEqual( const ::com::sun::star::awt::Rectangle& rA, const ::com::sun::star::awt::Rectangle& rB )
665 		{
666 			return (rA.X == rB.X && rA.Y == rB.Y && rA.Width == rB.Width && rA.Height == rB.Height);
667 		}
668     } // namespace bgfxtools
669 
670 } // namespace canvas
671