1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/geometry/RealSize2D.hpp>
21 #include <com/sun/star/geometry/RealPoint2D.hpp>
22 #include <com/sun/star/geometry/RealRectangle2D.hpp>
23 #include <com/sun/star/geometry/RealRectangle3D.hpp>
24 #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
25 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
26 #include <com/sun/star/geometry/AffineMatrix3D.hpp>
27 #include <com/sun/star/geometry/Matrix2D.hpp>
28 #include <com/sun/star/geometry/IntegerSize2D.hpp>
29 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
30 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
31 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
32 #include <com/sun/star/rendering/XGraphicDevice.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/awt/Point.hpp>
35 #include <com/sun/star/awt/Rectangle.hpp>
36 #include <basegfx/tools/unopolypolygon.hxx>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <basegfx/matrix/b3dhommatrix.hxx>
39 #include <basegfx/vector/b2dsize.hxx>
40 #include <basegfx/point/b2dpoint.hxx>
41 #include <basegfx/range/b2drectangle.hxx>
42 #include <basegfx/range/b3drange.hxx>
43 #include <basegfx/vector/b2isize.hxx>
44 #include <basegfx/point/b2ipoint.hxx>
45 #include <basegfx/range/b2irectangle.hxx>
46 #include <basegfx/range/b2ibox.hxx>
47 #include <basegfx/polygon/b2dpolygon.hxx>
48 #include <basegfx/polygon/b2dpolypolygon.hxx>
49 #include <basegfx/tools/canvastools.hxx>
52 using namespace ::com::sun::star
;
61 uno::Sequence
< geometry::RealBezierSegment2D
> bezierSequenceFromB2DPolygon(const ::basegfx::B2DPolygon
& rPoly
)
63 const sal_uInt32
nPointCount(rPoly
.count());
64 uno::Sequence
< geometry::RealBezierSegment2D
> outputSequence(nPointCount
);
65 geometry::RealBezierSegment2D
* pOutput
= outputSequence
.getArray();
67 // fill sequences and imply clodes polygon on this implementation layer
68 for(sal_uInt32
a(0); a
< nPointCount
; a
++)
70 const basegfx::B2DPoint
aStart(rPoly
.getB2DPoint(a
));
71 const basegfx::B2DPoint
aControlA(rPoly
.getNextControlPoint(a
));
72 const basegfx::B2DPoint
aControlB(rPoly
.getPrevControlPoint((a
+ 1) % nPointCount
));
74 pOutput
[a
] = geometry::RealBezierSegment2D(
75 aStart
.getX(), aStart
.getY(),
76 aControlA
.getX(), aControlA
.getY(),
77 aControlB
.getX(), aControlB
.getY());
80 return outputSequence
;
83 uno::Sequence
< geometry::RealPoint2D
> pointSequenceFromB2DPolygon( const ::basegfx::B2DPolygon
& rPoly
)
85 const sal_uInt32
nNumPoints( rPoly
.count() );
87 uno::Sequence
< geometry::RealPoint2D
> outputSequence( nNumPoints
);
88 geometry::RealPoint2D
* pOutput
= outputSequence
.getArray();
90 // fill sequence from polygon
92 for( i
=0; i
<nNumPoints
; ++i
)
94 const ::basegfx::B2DPoint
aPoint( rPoly
.getB2DPoint(i
) );
96 pOutput
[i
] = geometry::RealPoint2D( aPoint
.getX(),
100 return outputSequence
;
104 //---------------------------------------------------------------------------------------
106 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > bezierSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
108 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
111 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > outputSequence( nNumPolies
);
112 uno::Sequence
< geometry::RealBezierSegment2D
>* pOutput
= outputSequence
.getArray();
114 for( i
=0; i
<nNumPolies
; ++i
)
116 pOutput
[i
] = bezierSequenceFromB2DPolygon( rPolyPoly
.getB2DPolygon(i
) );
119 return outputSequence
;
122 //---------------------------------------------------------------------------------------
124 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > pointSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
126 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
129 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > outputSequence( nNumPolies
);
130 uno::Sequence
< geometry::RealPoint2D
>* pOutput
= outputSequence
.getArray();
132 for( i
=0; i
<nNumPolies
; ++i
)
134 pOutput
[i
] = pointSequenceFromB2DPolygon( rPolyPoly
.getB2DPolygon(i
) );
137 return outputSequence
;
140 //---------------------------------------------------------------------------------------
142 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromB2DPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
143 const ::basegfx::B2DPolygon
& rPoly
)
145 uno::Reference
< rendering::XPolyPolygon2D
> xRes
;
147 if( !xGraphicDevice
.is() )
150 if( rPoly
.areControlPointsUsed() )
152 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > outputSequence( 1 );
153 outputSequence
[0] = bezierSequenceFromB2DPolygon( rPoly
);
155 xRes
.set( xGraphicDevice
->createCompatibleBezierPolyPolygon( outputSequence
),
160 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > outputSequence( 1 );
161 outputSequence
[0] = pointSequenceFromB2DPolygon( rPoly
);
163 xRes
.set( xGraphicDevice
->createCompatibleLinePolyPolygon( outputSequence
),
167 if( xRes
.is() && rPoly
.isClosed() )
168 xRes
->setClosed( 0, sal_True
);
173 //---------------------------------------------------------------------------------------
175 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromB2DPolyPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
176 const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
178 uno::Reference
< rendering::XPolyPolygon2D
> xRes
;
180 if( !xGraphicDevice
.is() )
183 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
186 if( rPolyPoly
.areControlPointsUsed() )
188 xRes
.set( xGraphicDevice
->createCompatibleBezierPolyPolygon(
189 bezierSequenceSequenceFromB2DPolyPolygon( rPolyPoly
) ),
194 xRes
.set( xGraphicDevice
->createCompatibleLinePolyPolygon(
195 pointSequenceSequenceFromB2DPolyPolygon( rPolyPoly
) ),
199 for( i
=0; i
<nNumPolies
; ++i
)
201 xRes
->setClosed( i
, rPolyPoly
.getB2DPolygon(i
).isClosed() );
207 //---------------------------------------------------------------------------------------
209 ::basegfx::B2DPolygon
polygonFromPoint2DSequence( const uno::Sequence
< geometry::RealPoint2D
>& points
)
211 const sal_Int32
nCurrSize( points
.getLength() );
213 ::basegfx::B2DPolygon aPoly
;
215 for( sal_Int32 nCurrPoint
=0; nCurrPoint
<nCurrSize
; ++nCurrPoint
)
216 aPoly
.append( b2DPointFromRealPoint2D( points
[nCurrPoint
] ) );
221 //---------------------------------------------------------------------------------------
223 ::basegfx::B2DPolyPolygon
polyPolygonFromPoint2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> >& points
)
225 ::basegfx::B2DPolyPolygon aRes
;
227 for( sal_Int32 nCurrPoly
=0; nCurrPoly
<points
.getLength(); ++nCurrPoly
)
229 aRes
.append( polygonFromPoint2DSequence( points
[nCurrPoly
] ) );
235 //---------------------------------------------------------------------------------------
237 ::basegfx::B2DPolygon
polygonFromBezier2DSequence( const uno::Sequence
< geometry::RealBezierSegment2D
>& curves
)
239 const sal_Int32
nSize(curves
.getLength());
240 basegfx::B2DPolygon aRetval
;
244 // prepare start with providing a start point. Use the first point from
245 // the sequence for this
246 const geometry::RealBezierSegment2D
& rFirstSegment(curves
[0]); // #i79917# first segment, not last
247 aRetval
.append(basegfx::B2DPoint(rFirstSegment
.Px
, rFirstSegment
.Py
));
249 for(sal_Int32
a(0); a
< nSize
; a
++)
251 const geometry::RealBezierSegment2D
& rCurrSegment(curves
[a
]);
252 const geometry::RealBezierSegment2D
& rNextSegment(curves
[(a
+ 1) % nSize
]);
254 // append curved edge with the control points and the next point
255 aRetval
.appendBezierSegment(
256 basegfx::B2DPoint(rCurrSegment
.C1x
, rCurrSegment
.C1y
),
257 basegfx::B2DPoint(rCurrSegment
.C2x
, rCurrSegment
.C2y
), // #i79917# Argh! An x for an y!!
258 basegfx::B2DPoint(rNextSegment
.Px
, rNextSegment
.Py
));
261 // rescue the control point and remove the now double-added point
262 aRetval
.setPrevControlPoint(0, aRetval
.getPrevControlPoint(aRetval
.count() - 1));
263 aRetval
.remove(aRetval
.count() - 1);
269 //---------------------------------------------------------------------------------------
271 ::basegfx::B2DPolyPolygon
polyPolygonFromBezier2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> >& curves
)
273 ::basegfx::B2DPolyPolygon aRes
;
275 for( sal_Int32 nCurrPoly
=0; nCurrPoly
<curves
.getLength(); ++nCurrPoly
)
277 aRes
.append( polygonFromBezier2DSequence( curves
[nCurrPoly
] ) );
283 //---------------------------------------------------------------------------------------
285 ::basegfx::B2DPolyPolygon
b2DPolyPolygonFromXPolyPolygon2D( const uno::Reference
< rendering::XPolyPolygon2D
>& xPoly
)
287 ::basegfx::unotools::UnoPolyPolygon
* pPolyImpl
=
288 dynamic_cast< ::basegfx::unotools::UnoPolyPolygon
* >( xPoly
.get() );
292 return pPolyImpl
->getPolyPolygon();
296 // not a known implementation object - try data source
298 const sal_Int32
nPolys( xPoly
->getNumberOfPolygons() );
300 uno::Reference
< rendering::XBezierPolyPolygon2D
> xBezierPoly(
304 if( xBezierPoly
.is() )
306 return ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(
307 xBezierPoly
->getBezierSegments( 0,
314 uno::Reference
< rendering::XLinePolyPolygon2D
> xLinePoly(
318 // no implementation class and no data provider
319 // found - contract violation.
320 if( !xLinePoly
.is() )
322 throw lang::IllegalArgumentException(
324 "basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(): Invalid input"
325 "poly-polygon, cannot retrieve vertex data"),
326 uno::Reference
< uno::XInterface
>(),
330 return ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence(
331 xLinePoly
->getPoints( 0,
339 //---------------------------------------------------------------------------------------
341 ::basegfx::B2DHomMatrix
& homMatrixFromAffineMatrix( ::basegfx::B2DHomMatrix
& output
,
342 const geometry::AffineMatrix2D
& input
)
344 // ensure last row is [0,0,1] (and optimized away)
347 output
.set(0,0, input
.m00
);
348 output
.set(0,1, input
.m01
);
349 output
.set(0,2, input
.m02
);
350 output
.set(1,0, input
.m10
);
351 output
.set(1,1, input
.m11
);
352 output
.set(1,2, input
.m12
);
357 ::basegfx::B3DHomMatrix
homMatrixFromAffineMatrix3D( const ::com::sun::star::geometry::AffineMatrix3D
& input
)
359 ::basegfx::B3DHomMatrix output
;
361 output
.set(0,0, input
.m00
);
362 output
.set(0,1, input
.m01
);
363 output
.set(0,2, input
.m02
);
364 output
.set(0,3, input
.m03
);
366 output
.set(1,0, input
.m10
);
367 output
.set(1,1, input
.m11
);
368 output
.set(1,2, input
.m12
);
369 output
.set(1,3, input
.m13
);
371 output
.set(2,0, input
.m20
);
372 output
.set(2,1, input
.m21
);
373 output
.set(2,2, input
.m22
);
374 output
.set(2,3, input
.m23
);
379 geometry::AffineMatrix2D
& affineMatrixFromHomMatrix( geometry::AffineMatrix2D
& output
,
380 const ::basegfx::B2DHomMatrix
& input
)
382 output
.m00
= input
.get(0,0);
383 output
.m01
= input
.get(0,1);
384 output
.m02
= input
.get(0,2);
385 output
.m10
= input
.get(1,0);
386 output
.m11
= input
.get(1,1);
387 output
.m12
= input
.get(1,2);
392 geometry::AffineMatrix3D
& affineMatrixFromHomMatrix3D(
393 geometry::AffineMatrix3D
& output
,
394 const ::basegfx::B3DHomMatrix
& input
)
396 output
.m00
= input
.get(0,0);
397 output
.m01
= input
.get(0,1);
398 output
.m02
= input
.get(0,2);
399 output
.m03
= input
.get(0,3);
401 output
.m10
= input
.get(1,0);
402 output
.m11
= input
.get(1,1);
403 output
.m12
= input
.get(1,2);
404 output
.m13
= input
.get(1,3);
406 output
.m20
= input
.get(2,0);
407 output
.m21
= input
.get(2,1);
408 output
.m22
= input
.get(2,2);
409 output
.m23
= input
.get(2,3);
414 //---------------------------------------------------------------------------------------
416 ::basegfx::B2DHomMatrix
& homMatrixFromMatrix( ::basegfx::B2DHomMatrix
& output
,
417 const geometry::Matrix2D
& input
)
419 // ensure last row is [0,0,1] (and optimized away)
422 output
.set(0,0, input
.m00
);
423 output
.set(0,1, input
.m01
);
424 output
.set(1,0, input
.m10
);
425 output
.set(1,1, input
.m11
);
430 //---------------------------------------------------------------------------------------
432 geometry::RealSize2D
size2DFromB2DSize( const ::basegfx::B2DVector
& rVec
)
434 return geometry::RealSize2D( rVec
.getX(),
438 geometry::RealPoint2D
point2DFromB2DPoint( const ::basegfx::B2DPoint
& rPoint
)
440 return geometry::RealPoint2D( rPoint
.getX(),
444 geometry::RealRectangle2D
rectangle2DFromB2DRectangle( const ::basegfx::B2DRange
& rRect
)
446 return geometry::RealRectangle2D( rRect
.getMinX(),
452 geometry::RealRectangle3D
rectangle3DFromB3DRectangle( const ::basegfx::B3DRange
& rRect
)
454 return geometry::RealRectangle3D( rRect
.getMinX(),
462 ::basegfx::B2DPoint
b2DPointFromRealPoint2D( const geometry::RealPoint2D
& rPoint
)
464 return ::basegfx::B2DPoint( rPoint
.X
,
468 ::basegfx::B2DRange
b2DRectangleFromRealRectangle2D( const geometry::RealRectangle2D
& rRect
)
470 return ::basegfx::B2DRange( rRect
.X1
,
476 ::basegfx::B3DRange
b3DRectangleFromRealRectangle3D( const geometry::RealRectangle3D
& rRect
)
478 return ::basegfx::B3DRange( rRect
.X1
,
486 geometry::IntegerSize2D
integerSize2DFromB2ISize( const ::basegfx::B2IVector
& rSize
)
488 return geometry::IntegerSize2D( rSize
.getX(),
492 ::basegfx::B2IVector
b2ISizeFromIntegerSize2D( const geometry::IntegerSize2D
& rSize
)
494 return ::basegfx::B2IVector( rSize
.Width
,
498 ::basegfx::B2IRange
b2IRectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D
& rRectangle
)
500 return ::basegfx::B2IRange( rRectangle
.X1
, rRectangle
.Y1
,
501 rRectangle
.X2
, rRectangle
.Y2
);
504 ::basegfx::B2IRange
b2IRectangleFromAwtRectangle( const awt::Rectangle
& rRect
)
506 return ::basegfx::B2IRange( rRect
.X
,
508 rRect
.X
+ rRect
.Width
,
509 rRect
.Y
+ rRect
.Height
);
512 ::basegfx::B2IBox
b2ISurroundingBoxFromB2DRange( const ::basegfx::B2DRange
& rRange
)
514 return ::basegfx::B2IBox( static_cast<sal_Int32
>( floor(rRange
.getMinX()) ),
515 static_cast<sal_Int32
>( floor(rRange
.getMinY()) ),
516 static_cast<sal_Int32
>( ceil(rRange
.getMaxX()) ),
517 static_cast<sal_Int32
>( ceil(rRange
.getMaxY()) ) );
520 ::basegfx::B2IRange
b2ISurroundingRangeFromB2DRange( const ::basegfx::B2DRange
& rRange
)
522 return ::basegfx::B2IRange( static_cast<sal_Int32
>( floor(rRange
.getMinX()) ),
523 static_cast<sal_Int32
>( floor(rRange
.getMinY()) ),
524 static_cast<sal_Int32
>( ceil(rRange
.getMaxX()) ),
525 static_cast<sal_Int32
>( ceil(rRange
.getMaxY()) ) );
528 ::basegfx::B2DRange
b2DSurroundingIntegerRangeFromB2DRange( const ::basegfx::B2DRange
& rRange
)
530 return ::basegfx::B2DRange( floor(rRange
.getMinX()),
531 floor(rRange
.getMinY()),
532 ceil(rRange
.getMaxX()),
533 ceil(rRange
.getMaxY()) );
536 } // namespace bgfxtools
538 } // namespace canvas
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */