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