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/lang/IllegalArgumentException.hpp>
32 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
33 #include <com/sun/star/rendering/XGraphicDevice.hpp>
34 #include <com/sun/star/awt/Size.hpp>
35 #include <com/sun/star/awt/Point.hpp>
36 #include <com/sun/star/awt/Rectangle.hpp>
37 #include <basegfx/utils/unopolypolygon.hxx>
38 #include <basegfx/matrix/b2dhommatrix.hxx>
39 #include <basegfx/matrix/b3dhommatrix.hxx>
40 #include <basegfx/vector/b2dsize.hxx>
41 #include <basegfx/point/b2dpoint.hxx>
42 #include <basegfx/range/b2drectangle.hxx>
43 #include <basegfx/range/b3drange.hxx>
44 #include <basegfx/vector/b2isize.hxx>
45 #include <basegfx/point/b2ipoint.hxx>
46 #include <basegfx/range/b2irectangle.hxx>
47 #include <basegfx/range/b2ibox.hxx>
48 #include <basegfx/polygon/b2dpolygon.hxx>
49 #include <basegfx/polygon/b2dpolypolygon.hxx>
50 #include <basegfx/utils/canvastools.hxx>
53 using namespace ::com::sun::star
;
62 uno::Sequence
< geometry::RealBezierSegment2D
> bezierSequenceFromB2DPolygon(const ::basegfx::B2DPolygon
& rPoly
)
64 const sal_uInt32
nPointCount(rPoly
.count());
65 uno::Sequence
< geometry::RealBezierSegment2D
> outputSequence(nPointCount
);
66 geometry::RealBezierSegment2D
* pOutput
= outputSequence
.getArray();
68 // fill sequences and imply closed polygon on this implementation layer
69 for(sal_uInt32
a(0); a
< nPointCount
; a
++)
71 const basegfx::B2DPoint
aStart(rPoly
.getB2DPoint(a
));
72 const basegfx::B2DPoint
aControlA(rPoly
.getNextControlPoint(a
));
73 const basegfx::B2DPoint
aControlB(rPoly
.getPrevControlPoint((a
+ 1) % nPointCount
));
75 pOutput
[a
] = geometry::RealBezierSegment2D(
76 aStart
.getX(), aStart
.getY(),
77 aControlA
.getX(), aControlA
.getY(),
78 aControlB
.getX(), aControlB
.getY());
81 return outputSequence
;
84 uno::Sequence
< geometry::RealPoint2D
> pointSequenceFromB2DPolygon( const ::basegfx::B2DPolygon
& rPoly
)
86 const sal_uInt32
nNumPoints( rPoly
.count() );
88 uno::Sequence
< geometry::RealPoint2D
> outputSequence( nNumPoints
);
89 geometry::RealPoint2D
* pOutput
= outputSequence
.getArray();
91 // fill sequence from polygon
93 for( i
=0; i
<nNumPoints
; ++i
)
95 const ::basegfx::B2DPoint
aPoint( rPoly
.getB2DPoint(i
) );
97 pOutput
[i
] = geometry::RealPoint2D( aPoint
.getX(),
101 return outputSequence
;
105 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > bezierSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
107 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
110 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > outputSequence( nNumPolies
);
111 uno::Sequence
< geometry::RealBezierSegment2D
>* pOutput
= outputSequence
.getArray();
113 for( i
=0; i
<nNumPolies
; ++i
)
115 pOutput
[i
] = bezierSequenceFromB2DPolygon( rPolyPoly
.getB2DPolygon(i
) );
118 return outputSequence
;
121 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > pointSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
123 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
126 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > outputSequence( nNumPolies
);
127 uno::Sequence
< geometry::RealPoint2D
>* pOutput
= outputSequence
.getArray();
129 for( i
=0; i
<nNumPolies
; ++i
)
131 pOutput
[i
] = pointSequenceFromB2DPolygon( rPolyPoly
.getB2DPolygon(i
) );
134 return outputSequence
;
137 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromB2DPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
138 const ::basegfx::B2DPolygon
& rPoly
)
140 uno::Reference
< rendering::XPolyPolygon2D
> xRes
;
142 if( !xGraphicDevice
.is() )
145 if( rPoly
.areControlPointsUsed() )
147 uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> > outputSequence( 1 );
148 outputSequence
[0] = bezierSequenceFromB2DPolygon( rPoly
);
150 xRes
.set( xGraphicDevice
->createCompatibleBezierPolyPolygon( outputSequence
),
155 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > outputSequence( 1 );
156 outputSequence
[0] = pointSequenceFromB2DPolygon( rPoly
);
158 xRes
.set( xGraphicDevice
->createCompatibleLinePolyPolygon( outputSequence
),
162 if( xRes
.is() && rPoly
.isClosed() )
163 xRes
->setClosed( 0, true );
168 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromB2DPolyPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
169 const ::basegfx::B2DPolyPolygon
& rPolyPoly
)
171 uno::Reference
< rendering::XPolyPolygon2D
> xRes
;
173 if( !xGraphicDevice
.is() )
176 const sal_uInt32
nNumPolies( rPolyPoly
.count() );
179 if( rPolyPoly
.areControlPointsUsed() )
181 xRes
.set( xGraphicDevice
->createCompatibleBezierPolyPolygon(
182 bezierSequenceSequenceFromB2DPolyPolygon( rPolyPoly
) ),
187 xRes
.set( xGraphicDevice
->createCompatibleLinePolyPolygon(
188 pointSequenceSequenceFromB2DPolyPolygon( rPolyPoly
) ),
192 for( i
=0; i
<nNumPolies
; ++i
)
194 xRes
->setClosed( i
, rPolyPoly
.getB2DPolygon(i
).isClosed() );
200 ::basegfx::B2DPolygon
polygonFromPoint2DSequence( const uno::Sequence
< geometry::RealPoint2D
>& points
)
202 const sal_Int32
nCurrSize( points
.getLength() );
204 ::basegfx::B2DPolygon aPoly
;
206 for( sal_Int32 nCurrPoint
=0; nCurrPoint
<nCurrSize
; ++nCurrPoint
)
207 aPoly
.append( b2DPointFromRealPoint2D( points
[nCurrPoint
] ) );
212 ::basegfx::B2DPolyPolygon
polyPolygonFromPoint2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> >& points
)
214 ::basegfx::B2DPolyPolygon aRes
;
216 for( sal_Int32 nCurrPoly
=0; nCurrPoly
<points
.getLength(); ++nCurrPoly
)
218 aRes
.append( polygonFromPoint2DSequence( points
[nCurrPoly
] ) );
224 ::basegfx::B2DPolygon
polygonFromBezier2DSequence( const uno::Sequence
< geometry::RealBezierSegment2D
>& curves
)
226 const sal_Int32
nSize(curves
.getLength());
227 basegfx::B2DPolygon aRetval
;
231 // prepare start with providing a start point. Use the first point from
232 // the sequence for this
233 const geometry::RealBezierSegment2D
& rFirstSegment(curves
[0]); // #i79917# first segment, not last
234 aRetval
.append(basegfx::B2DPoint(rFirstSegment
.Px
, rFirstSegment
.Py
));
236 for(sal_Int32
a(0); a
< nSize
; a
++)
238 const geometry::RealBezierSegment2D
& rCurrSegment(curves
[a
]);
239 const geometry::RealBezierSegment2D
& rNextSegment(curves
[(a
+ 1) % nSize
]);
241 // append curved edge with the control points and the next point
242 aRetval
.appendBezierSegment(
243 basegfx::B2DPoint(rCurrSegment
.C1x
, rCurrSegment
.C1y
),
244 basegfx::B2DPoint(rCurrSegment
.C2x
, rCurrSegment
.C2y
), // #i79917# Argh! An x for an y!!
245 basegfx::B2DPoint(rNextSegment
.Px
, rNextSegment
.Py
));
248 // rescue the control point and remove the now double-added point
249 aRetval
.setPrevControlPoint(0, aRetval
.getPrevControlPoint(aRetval
.count() - 1));
250 aRetval
.remove(aRetval
.count() - 1);
256 ::basegfx::B2DPolyPolygon
polyPolygonFromBezier2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> >& curves
)
258 ::basegfx::B2DPolyPolygon aRes
;
260 for( sal_Int32 nCurrPoly
=0; nCurrPoly
<curves
.getLength(); ++nCurrPoly
)
262 aRes
.append( polygonFromBezier2DSequence( curves
[nCurrPoly
] ) );
268 ::basegfx::B2DPolyPolygon
b2DPolyPolygonFromXPolyPolygon2D( const uno::Reference
< rendering::XPolyPolygon2D
>& xPoly
)
270 ::basegfx::unotools::UnoPolyPolygon
* pPolyImpl
=
271 dynamic_cast< ::basegfx::unotools::UnoPolyPolygon
* >( xPoly
.get() );
275 return pPolyImpl
->getPolyPolygon();
279 // not a known implementation object - try data source
281 const sal_Int32
nPolys( xPoly
->getNumberOfPolygons() );
283 uno::Reference
< rendering::XBezierPolyPolygon2D
> xBezierPoly(
287 if( xBezierPoly
.is() )
289 return ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(
290 xBezierPoly
->getBezierSegments( 0,
297 uno::Reference
< rendering::XLinePolyPolygon2D
> xLinePoly(
301 // no implementation class and no data provider
302 // found - contract violation.
303 if( !xLinePoly
.is() )
305 throw lang::IllegalArgumentException(
306 "basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(): Invalid input"
307 "poly-polygon, cannot retrieve vertex data",
308 uno::Reference
< uno::XInterface
>(),
312 return ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence(
313 xLinePoly
->getPoints( 0,
321 ::basegfx::B2DHomMatrix
& homMatrixFromAffineMatrix( ::basegfx::B2DHomMatrix
& output
,
322 const geometry::AffineMatrix2D
& input
)
324 // ensure last row is [0,0,1] (and optimized away)
327 output
.set(0,0, input
.m00
);
328 output
.set(0,1, input
.m01
);
329 output
.set(0,2, input
.m02
);
330 output
.set(1,0, input
.m10
);
331 output
.set(1,1, input
.m11
);
332 output
.set(1,2, input
.m12
);
337 ::basegfx::B3DHomMatrix
homMatrixFromAffineMatrix3D( const ::css::geometry::AffineMatrix3D
& input
)
339 ::basegfx::B3DHomMatrix output
;
341 output
.set(0,0, input
.m00
);
342 output
.set(0,1, input
.m01
);
343 output
.set(0,2, input
.m02
);
344 output
.set(0,3, input
.m03
);
346 output
.set(1,0, input
.m10
);
347 output
.set(1,1, input
.m11
);
348 output
.set(1,2, input
.m12
);
349 output
.set(1,3, input
.m13
);
351 output
.set(2,0, input
.m20
);
352 output
.set(2,1, input
.m21
);
353 output
.set(2,2, input
.m22
);
354 output
.set(2,3, input
.m23
);
359 geometry::AffineMatrix2D
& affineMatrixFromHomMatrix( geometry::AffineMatrix2D
& output
,
360 const ::basegfx::B2DHomMatrix
& input
)
362 output
.m00
= input
.get(0,0);
363 output
.m01
= input
.get(0,1);
364 output
.m02
= input
.get(0,2);
365 output
.m10
= input
.get(1,0);
366 output
.m11
= input
.get(1,1);
367 output
.m12
= input
.get(1,2);
372 geometry::AffineMatrix3D
& affineMatrixFromHomMatrix3D(
373 geometry::AffineMatrix3D
& output
,
374 const ::basegfx::B3DHomMatrix
& input
)
376 output
.m00
= input
.get(0,0);
377 output
.m01
= input
.get(0,1);
378 output
.m02
= input
.get(0,2);
379 output
.m03
= input
.get(0,3);
381 output
.m10
= input
.get(1,0);
382 output
.m11
= input
.get(1,1);
383 output
.m12
= input
.get(1,2);
384 output
.m13
= input
.get(1,3);
386 output
.m20
= input
.get(2,0);
387 output
.m21
= input
.get(2,1);
388 output
.m22
= input
.get(2,2);
389 output
.m23
= input
.get(2,3);
394 geometry::RealSize2D
size2DFromB2DSize( const ::basegfx::B2DVector
& rVec
)
396 return geometry::RealSize2D( rVec
.getX(),
400 geometry::RealPoint2D
point2DFromB2DPoint( const ::basegfx::B2DPoint
& rPoint
)
402 return geometry::RealPoint2D( rPoint
.getX(),
406 geometry::RealRectangle2D
rectangle2DFromB2DRectangle( const ::basegfx::B2DRange
& rRect
)
408 return geometry::RealRectangle2D( rRect
.getMinX(),
414 geometry::RealRectangle3D
rectangle3DFromB3DRectangle( const ::basegfx::B3DRange
& rRect
)
416 return geometry::RealRectangle3D( rRect
.getMinX(),
424 ::basegfx::B2DPoint
b2DPointFromRealPoint2D( const geometry::RealPoint2D
& rPoint
)
426 return ::basegfx::B2DPoint( rPoint
.X
,
430 ::basegfx::B2DRange
b2DRectangleFromRealRectangle2D( const geometry::RealRectangle2D
& rRect
)
432 return ::basegfx::B2DRange( rRect
.X1
,
438 ::basegfx::B3DRange
b3DRectangleFromRealRectangle3D( const geometry::RealRectangle3D
& rRect
)
440 return ::basegfx::B3DRange( rRect
.X1
,
448 geometry::IntegerSize2D
integerSize2DFromB2ISize( const ::basegfx::B2IVector
& rSize
)
450 return geometry::IntegerSize2D( rSize
.getX(),
454 ::basegfx::B2IVector
b2ISizeFromIntegerSize2D( const geometry::IntegerSize2D
& rSize
)
456 return ::basegfx::B2IVector( rSize
.Width
,
460 ::basegfx::B2IRange
b2IRectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D
& rRectangle
)
462 return ::basegfx::B2IRange( rRectangle
.X1
, rRectangle
.Y1
,
463 rRectangle
.X2
, rRectangle
.Y2
);
466 ::basegfx::B2IRange
b2IRectangleFromAwtRectangle( const awt::Rectangle
& rRect
)
468 return ::basegfx::B2IRange( rRect
.X
,
470 rRect
.X
+ rRect
.Width
,
471 rRect
.Y
+ rRect
.Height
);
474 ::basegfx::B2IRange
b2ISurroundingRangeFromB2DRange( const ::basegfx::B2DRange
& rRange
)
476 return ::basegfx::B2IRange( static_cast<sal_Int32
>( floor(rRange
.getMinX()) ),
477 static_cast<sal_Int32
>( floor(rRange
.getMinY()) ),
478 static_cast<sal_Int32
>( ceil(rRange
.getMaxX()) ),
479 static_cast<sal_Int32
>( ceil(rRange
.getMaxY()) ) );
482 ::basegfx::B2DRange
b2DSurroundingIntegerRangeFromB2DRange( const ::basegfx::B2DRange
& rRange
)
484 return ::basegfx::B2DRange( floor(rRange
.getMinX()),
485 floor(rRange
.getMinY()),
486 ceil(rRange
.getMaxX()),
487 ceil(rRange
.getMaxY()) );
490 } // namespace bgfxtools
492 } // namespace canvas
494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */