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 <ShapeFactory.hxx>
21 #include <BaseGFXHelper.hxx>
22 #include <ViewDefines.hxx>
24 #include <CommonConverters.hxx>
25 #include <RelativeSizeHelper.hxx>
26 #include <PropertyMapper.hxx>
27 #include <VLineProperties.hxx>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/beans/XMultiPropertySet.hpp>
30 #include <com/sun/star/chart2/XFormattedString.hpp>
31 #include <com/sun/star/drawing/CircleKind.hpp>
32 #include <com/sun/star/drawing/DoubleSequence.hpp>
33 #include <com/sun/star/drawing/FlagSequence.hpp>
34 #include <com/sun/star/drawing/FillStyle.hpp>
35 #include <com/sun/star/drawing/LineStyle.hpp>
36 #include <com/sun/star/drawing/NormalsKind.hpp>
37 #include <com/sun/star/drawing/PointSequence.hpp>
38 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
39 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
40 #include <com/sun/star/drawing/TextureProjectionMode.hpp>
41 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
42 #include <com/sun/star/drawing/XShapes2.hpp>
43 #include <com/sun/star/graphic/XGraphic.hpp>
44 #include <com/sun/star/drawing/XShapes.hpp>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/text/XText.hpp>
47 #include <com/sun/star/uno/Sequence.hxx>
48 #include <com/sun/star/uno/Any.hxx>
50 #include <editeng/unoprnms.hxx>
51 #include <rtl/math.hxx>
53 #include <basegfx/point/b2dpoint.hxx>
54 #include <basegfx/matrix/b3dhommatrix.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <tools/helpers.hxx>
57 #include <sal/log.hxx>
61 using namespace ::com::sun::star
;
62 using ::com::sun::star::uno::Reference
;
70 void lcl_addProperty(uno::Sequence
<OUString
> & rPropertyNames
, uno::Sequence
<uno::Any
> & rPropertyValues
,
71 OUString
const & rName
, uno::Any
const & rAny
)
73 rPropertyNames
.realloc(rPropertyNames
.getLength() + 1);
74 rPropertyNames
[rPropertyNames
.getLength() - 1] = rName
;
76 rPropertyValues
.realloc(rPropertyValues
.getLength() + 1);
77 rPropertyValues
[rPropertyValues
.getLength() - 1] = rAny
;
80 } // end anonymous namespace
82 uno::Reference
< drawing::XShapes
> ShapeFactory::getOrCreateChartRootShape(
83 const uno::Reference
< drawing::XDrawPage
>& xDrawPage
)
85 uno::Reference
<drawing::XShapes
> xRet
= ShapeFactory::getChartRootShape(xDrawPage
);
89 // Create a new root shape and set it to the bottom of the page. The root
90 // shape is identified by having the name com.sun.star.chart2.shapes.
91 uno::Reference
<drawing::XShape
> xShape(
92 m_xShapeFactory
->createInstance("com.sun.star.drawing.GroupShape"), uno::UNO_QUERY
);
93 uno::Reference
<drawing::XShapes2
> xShapes2(xDrawPage
, uno::UNO_QUERY_THROW
);
94 xShapes2
->addBottom(xShape
);
96 setShapeName(xShape
, "com.sun.star.chart2.shapes");
97 xShape
->setSize(awt::Size(0,0));
99 xRet
.set(xShape
, uno::UNO_QUERY
);
103 void ShapeFactory::setPageSize(const uno::Reference
<drawing::XShapes
>&, const awt::Size
&) {}
105 // diverse tools::PolyPolygon create methods
107 static uno::Any
createPolyPolygon_Cube(
108 const drawing::Direction3D
& rSize
, double fRoundedEdge
, bool bRounded
)
110 OSL_PRECOND(fRoundedEdge
>=0, "fRoundedEdge needs to be >= 0");
112 // always use extra points, so set percent diagonal to 0.4 which is 0% in the UI (old Chart comment)
113 if( fRoundedEdge
== 0.0 && bRounded
)
114 fRoundedEdge
= 0.4 / 200.0;
118 //fWidthH stands for Half Width
119 const double fWidthH
= rSize
.DirectionX
>=0.0? rSize
.DirectionX
/2.0 : -rSize
.DirectionX
/2.0;
120 const double fHeight
= rSize
.DirectionY
;
122 const double fHeightSign
= fHeight
>= 0.0 ? 1.0 : -1.0;
124 const double fOffset
= (fWidthH
* fRoundedEdge
) * 1.05; // increase by 5% for safety
125 const bool bRoundEdges
= fRoundedEdge
&& fOffset
< fWidthH
&& 2.0 * fOffset
< fHeightSign
*fHeight
;
126 const sal_Int32 nPointCount
= bRoundEdges
? 13 : 5;
128 drawing::PolyPolygonShape3D aPP
;
130 aPP
.SequenceX
.realloc(1);
131 aPP
.SequenceY
.realloc(1);
132 aPP
.SequenceZ
.realloc(1);
134 drawing::DoubleSequence
* pOuterSequenceX
= aPP
.SequenceX
.getArray();
135 drawing::DoubleSequence
* pOuterSequenceY
= aPP
.SequenceY
.getArray();
136 drawing::DoubleSequence
* pOuterSequenceZ
= aPP
.SequenceZ
.getArray();
138 pOuterSequenceX
->realloc(nPointCount
);
139 pOuterSequenceY
->realloc(nPointCount
);
140 pOuterSequenceZ
->realloc(nPointCount
);
142 double* pInnerSequenceX
= pOuterSequenceX
->getArray();
143 double* pInnerSequenceY
= pOuterSequenceY
->getArray();
144 double* pInnerSequenceZ
= pOuterSequenceZ
->getArray();
146 for(sal_Int32 nN
= nPointCount
; nN
--;)
147 *pInnerSequenceZ
++ = 0.0;
151 *pInnerSequenceY
++ = 0.0;
152 *pInnerSequenceY
++ = 0.0;
153 *pInnerSequenceY
++ = fHeight
;
154 *pInnerSequenceY
++ = fHeight
;
155 *pInnerSequenceY
++ = 0.0;
157 *pInnerSequenceX
++ = -fWidthH
;
158 *pInnerSequenceX
++ = fWidthH
;
159 *pInnerSequenceX
++ = fWidthH
;
160 *pInnerSequenceX
++ = -fWidthH
;
161 *pInnerSequenceX
++ = -fWidthH
;
165 *pInnerSequenceY
++ = 0.0;
166 *pInnerSequenceY
++ = 0.0;
167 *pInnerSequenceY
++ = 0.0;
168 *pInnerSequenceY
++ = fHeightSign
*fOffset
;
169 *pInnerSequenceY
++ = fHeight
- fHeightSign
*fOffset
;
170 *pInnerSequenceY
++ = fHeight
;
171 *pInnerSequenceY
++ = fHeight
;
172 *pInnerSequenceY
++ = fHeight
;
173 *pInnerSequenceY
++ = fHeight
;
174 *pInnerSequenceY
++ = fHeight
- fHeightSign
*fOffset
;
175 *pInnerSequenceY
++ = fHeightSign
*fOffset
;
176 *pInnerSequenceY
++ = 0.0;
177 *pInnerSequenceY
++ = 0.0;
179 *pInnerSequenceX
++ = -fWidthH
+ fOffset
;
180 *pInnerSequenceX
++ = fWidthH
- fOffset
;
181 *pInnerSequenceX
++ = fWidthH
;
182 *pInnerSequenceX
++ = fWidthH
;
183 *pInnerSequenceX
++ = fWidthH
;
184 *pInnerSequenceX
++ = fWidthH
;
185 *pInnerSequenceX
++ = fWidthH
- fOffset
;
186 *pInnerSequenceX
++ = -fWidthH
+ fOffset
;
187 *pInnerSequenceX
++ = -fWidthH
;
188 *pInnerSequenceX
++ = -fWidthH
;
189 *pInnerSequenceX
++ = -fWidthH
;
190 *pInnerSequenceX
++ = -fWidthH
;
191 *pInnerSequenceX
++ = -fWidthH
+ fOffset
;
193 return uno::Any( &aPP
, cppu::UnoType
<drawing::PolyPolygonShape3D
>::get());
196 static uno::Any
createPolyPolygon_Cylinder(
199 , sal_Int32
& nVerticalSegmentCount
)
201 //fHeight may be negative
202 OSL_PRECOND(fRadius
>0, "The radius of a cylinder needs to be > 0");
204 drawing::PolyPolygonShape3D aPP
;
206 nVerticalSegmentCount
=1;
208 aPP
.SequenceX
.realloc(3);
209 aPP
.SequenceY
.realloc(3);
210 aPP
.SequenceZ
.realloc(3);
212 drawing::DoubleSequence
* pOuterSequenceX
= aPP
.SequenceX
.getArray();
213 drawing::DoubleSequence
* pOuterSequenceY
= aPP
.SequenceY
.getArray();
214 drawing::DoubleSequence
* pOuterSequenceZ
= aPP
.SequenceZ
.getArray();
216 pOuterSequenceX
->realloc(2);
217 pOuterSequenceY
->realloc(2);
218 pOuterSequenceZ
->realloc(2);
220 double* pInnerSequenceX
= pOuterSequenceX
->getArray();
221 double* pInnerSequenceY
= pOuterSequenceY
->getArray();
222 double* pInnerSequenceZ
= pOuterSequenceZ
->getArray();
225 double fY2
= fHeight
;
230 for(sal_Int32 nN
= 2; nN
--;)
231 *pInnerSequenceZ
++ = 0.0;
233 *pInnerSequenceX
++ = 0.0;
234 *pInnerSequenceY
++ = fY1
;
236 *pInnerSequenceX
++ = fRadius
;
237 *pInnerSequenceY
++ = fY1
;
239 pOuterSequenceX
++;pOuterSequenceY
++;pOuterSequenceZ
++;
240 pOuterSequenceX
->realloc(2);
241 pOuterSequenceY
->realloc(2);
242 pOuterSequenceZ
->realloc(2);
244 pInnerSequenceX
= pOuterSequenceX
->getArray();
245 pInnerSequenceY
= pOuterSequenceY
->getArray();
246 pInnerSequenceZ
= pOuterSequenceZ
->getArray();
248 for(sal_Int32 nN
= 2; nN
--;)
249 *pInnerSequenceZ
++ = 0.0;
251 *pInnerSequenceX
++ = fRadius
;
252 *pInnerSequenceY
++ = fY1
;
254 *pInnerSequenceX
++ = fRadius
;
255 *pInnerSequenceY
++ = fY2
;
257 pOuterSequenceX
++;pOuterSequenceY
++;pOuterSequenceZ
++;
258 pOuterSequenceX
->realloc(2);
259 pOuterSequenceY
->realloc(2);
260 pOuterSequenceZ
->realloc(2);
262 pInnerSequenceX
= pOuterSequenceX
->getArray();
263 pInnerSequenceY
= pOuterSequenceY
->getArray();
264 pInnerSequenceZ
= pOuterSequenceZ
->getArray();
266 for(sal_Int32 nN
= 2; nN
--;)
267 *pInnerSequenceZ
++ = 0.0;
269 *pInnerSequenceX
++ = fRadius
;
270 *pInnerSequenceY
++ = fY2
;
272 *pInnerSequenceX
++ = 0.0;
273 *pInnerSequenceY
++ = fY2
;
275 return uno::Any( &aPP
, cppu::UnoType
<drawing::PolyPolygonShape3D
>::get());
278 static uno::Any
createPolyPolygon_Cone( double fHeight
, double fRadius
, double fTopHeight
279 , sal_Int32
& nVerticalSegmentCount
)
281 OSL_PRECOND(fRadius
>0, "The radius of a cone needs to be > 0");
283 //for stacked charts we need cones without top -> fTopHeight != 0 resp. bTopless == true
284 //fTopHeight indicates the high of the cutted top only (not the full height)
285 bool bTopless
= !::rtl::math::approxEqual( fHeight
, fHeight
+ fTopHeight
);
287 double r1
= 0.0, r2
= fRadius
;
289 // #i63212# fHeight may be negative, fTopHeight is always positive -> use fabs(fHeight)
290 r1
= fRadius
* fTopHeight
/(fabs(fHeight
)+fTopHeight
);
292 nVerticalSegmentCount
=1;
293 drawing::PolyPolygonShape3D aPP
;
295 aPP
.SequenceX
.realloc(2);
296 aPP
.SequenceY
.realloc(2);
297 aPP
.SequenceZ
.realloc(2);
299 drawing::DoubleSequence
* pOuterSequenceX
= aPP
.SequenceX
.getArray();
300 drawing::DoubleSequence
* pOuterSequenceY
= aPP
.SequenceY
.getArray();
301 drawing::DoubleSequence
* pOuterSequenceZ
= aPP
.SequenceZ
.getArray();
303 pOuterSequenceX
->realloc(2);
304 pOuterSequenceY
->realloc(2);
305 pOuterSequenceZ
->realloc(2);
307 double* pInnerSequenceX
= pOuterSequenceX
->getArray();
308 double* pInnerSequenceY
= pOuterSequenceY
->getArray();
309 double* pInnerSequenceZ
= pOuterSequenceZ
->getArray();
317 double fY3
= fHeight
;
325 for(sal_Int32 nN
= 2; nN
--;)
326 *pInnerSequenceZ
++ = 0.0;
328 *pInnerSequenceY
++ = fY1
;
329 *pInnerSequenceX
++ = fX1
;
331 *pInnerSequenceY
++ = fY2
;
332 *pInnerSequenceX
++ = fX2
;
334 pOuterSequenceX
++;pOuterSequenceY
++;pOuterSequenceZ
++;
335 pOuterSequenceX
->realloc(2);
336 pOuterSequenceY
->realloc(2);
337 pOuterSequenceZ
->realloc(2);
339 pInnerSequenceX
= pOuterSequenceX
->getArray();
340 pInnerSequenceY
= pOuterSequenceY
->getArray();
341 pInnerSequenceZ
= pOuterSequenceZ
->getArray();
343 for(sal_Int32 nN
= 2; nN
--;)
344 *pInnerSequenceZ
++ = 0.0;
346 *pInnerSequenceY
++ = fY2
;
347 *pInnerSequenceX
++ = fX2
;
349 *pInnerSequenceY
++ = fY3
;
350 *pInnerSequenceX
++ = fX3
;
352 return uno::Any( &aPP
, cppu::UnoType
<drawing::PolyPolygonShape3D
>::get());
355 // methods for 3D shape creation
357 uno::Reference
<drawing::XShape
>
358 ShapeFactory::createCube(
359 const uno::Reference
<drawing::XShapes
>& xTarget
360 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
361 , sal_Int32 nRotateZAngleHundredthDegree
362 , const uno::Reference
< beans::XPropertySet
>& xSourceProp
363 , const tPropertyNameMap
& rPropertyNameMap
372 if( xSourceProp
.is() )
374 drawing::LineStyle aLineStyle
;
375 xSourceProp
->getPropertyValue( "BorderStyle" ) >>= aLineStyle
;
376 if( aLineStyle
== drawing::LineStyle_SOLID
)
380 catch( const uno::Exception
& )
382 TOOLS_WARN_EXCEPTION("chart2", "" );
385 uno::Reference
<drawing::XShape
> xShape
= impl_createCube( xTarget
, rPosition
, rSize
, nRotateZAngleHundredthDegree
, bRounded
);
386 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
387 if( xSourceProp
.is())
388 PropertyMapper::setMappedProperties( xProp
, xSourceProp
, rPropertyNameMap
);
392 uno::Reference
<drawing::XShape
>
393 ShapeFactory::impl_createCube(
394 const uno::Reference
<drawing::XShapes
>& xTarget
395 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
396 , sal_Int32 nRotateZAngleHundredthDegree
403 uno::Reference
< drawing::XShape
> xShape(
404 m_xShapeFactory
->createInstance(
405 "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY
);
406 xTarget
->add(xShape
);
409 uno::Reference
<beans::XMultiPropertySet
> xMultiPropertySet(xShape
, uno::UNO_QUERY
);
410 OSL_ENSURE(xMultiPropertySet
.is(), "created shape offers no XMultiPropertySet");
411 if (xMultiPropertySet
.is())
416 double fDepth
= rSize
.DirectionZ
;
421 sal_Int16 nPercentDiagonal
= bRounded
? 3 : 0;
423 //Matrix for position
424 basegfx::B3DHomMatrix aHomMatrix
;
425 if (nRotateZAngleHundredthDegree
!= 0)
426 aHomMatrix
.rotate(0.0, 0.0, -nRotateZAngleHundredthDegree
/ 18000.00 * F_PI
);
427 aHomMatrix
.translate(rPosition
.PositionX
, rPosition
.PositionY
,
428 rPosition
.PositionZ
- (fDepth
/ 2.0));
430 uno::Sequence
<OUString
> aPropertyNames
{
431 UNO_NAME_3D_EXTRUDE_DEPTH
,
432 UNO_NAME_3D_PERCENT_DIAGONAL
,
433 UNO_NAME_3D_POLYPOLYGON3D
,
434 UNO_NAME_3D_TRANSFORM_MATRIX
,
437 uno::Sequence
<uno::Any
> aPropertyValues
{
438 uno::Any(sal_Int32(fDepth
)), // Depth
439 uno::Any(nPercentDiagonal
), // PercentDiagonal
440 createPolyPolygon_Cube(rSize
, double(nPercentDiagonal
) / 200.0, bRounded
),
441 uno::Any(B3DHomMatrixToHomogenMatrix(aHomMatrix
))
444 xMultiPropertySet
->setPropertyValues(aPropertyNames
, aPropertyValues
);
446 catch( const uno::Exception
& )
448 TOOLS_WARN_EXCEPTION("chart2", "" );
454 uno::Reference
<drawing::XShape
>
455 ShapeFactory::createCylinder(
456 const uno::Reference
<drawing::XShapes
>& xTarget
457 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
458 , sal_Int32 nRotateZAngleHundredthDegree
)
460 return impl_createConeOrCylinder(
461 xTarget
, rPosition
, rSize
, 0.0, nRotateZAngleHundredthDegree
, true );
464 uno::Reference
<drawing::XShape
>
465 ShapeFactory::createPyramid(
466 const uno::Reference
<drawing::XShapes
>& xTarget
467 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
468 , double fTopHeight
, bool bRotateZ
469 , const uno::Reference
< beans::XPropertySet
>& xSourceProp
470 , const tPropertyNameMap
& rPropertyNameMap
)
475 Reference
< drawing::XShapes
> xGroup( ShapeFactory::createGroup3D( xTarget
) );
477 bool bDoubleSided
= false;
478 short nRotatedTexture
= 0;
480 const double fWidth
= rSize
.DirectionX
;
481 const double fDepth
= rSize
.DirectionZ
;
482 const double fHeight
= rSize
.DirectionY
;
484 drawing::Position3D
aBottomP1( rPosition
.PositionX
, rPosition
.PositionY
, rPosition
.PositionZ
- fDepth
/2.0 );
486 aBottomP1
.PositionY
-= fWidth
/2.0;
488 aBottomP1
.PositionX
-= fWidth
/2.0;
489 drawing::Position3D
aBottomP2( aBottomP1
);
491 aBottomP2
.PositionY
+= fWidth
;
493 aBottomP2
.PositionX
+= fWidth
;
494 drawing::Position3D
aBottomP3( aBottomP2
);
495 drawing::Position3D
aBottomP4( aBottomP1
);
496 aBottomP3
.PositionZ
+= fDepth
;
497 aBottomP4
.PositionZ
+= fDepth
;
499 const double fTopFactor
= fTopHeight
/(fabs(fHeight
)+fTopHeight
);
500 drawing::Position3D
aTopP1( rPosition
.PositionX
, rPosition
.PositionY
, rPosition
.PositionZ
- fDepth
*fTopFactor
/2.0 );
503 aTopP1
.PositionY
-= fWidth
*fTopFactor
/2.0;
504 aTopP1
.PositionX
+= fHeight
;
508 aTopP1
.PositionX
-= fWidth
*fTopFactor
/2.0;
509 aTopP1
.PositionY
+= fHeight
;
511 drawing::Position3D
aTopP2( aTopP1
);
513 aTopP2
.PositionY
+= fWidth
*fTopFactor
;
515 aTopP2
.PositionX
+= fWidth
*fTopFactor
;
516 drawing::Position3D
aTopP3( aTopP2
);
517 drawing::Position3D
aTopP4( aTopP1
);
518 aTopP3
.PositionZ
+= fDepth
*fTopFactor
;
519 aTopP4
.PositionZ
+= fDepth
*fTopFactor
;
521 Stripe
aStripeBottom( aBottomP1
, aBottomP4
, aBottomP3
, aBottomP2
);
523 drawing::Position3D
aNormalsBottomP1( aBottomP1
);
524 drawing::Position3D
aNormalsBottomP2( aBottomP2
);
525 drawing::Position3D
aNormalsBottomP3( aBottomP3
);
526 drawing::Position3D
aNormalsBottomP4( aBottomP4
);
527 drawing::Position3D
aNormalsTopP1( aBottomP1
);
528 drawing::Position3D
aNormalsTopP2( aBottomP2
);
529 drawing::Position3D
aNormalsTopP3( aBottomP3
);
530 drawing::Position3D
aNormalsTopP4( aBottomP4
);
533 aNormalsTopP1
.PositionX
+= fHeight
;
534 aNormalsTopP2
.PositionX
+= fHeight
;
535 aNormalsTopP3
.PositionX
+= fHeight
;
536 aNormalsTopP4
.PositionX
+= fHeight
;
540 aNormalsTopP1
.PositionY
+= fHeight
;
541 aNormalsTopP2
.PositionY
+= fHeight
;
542 aNormalsTopP3
.PositionY
+= fHeight
;
543 aNormalsTopP4
.PositionY
+= fHeight
;
546 bool bInvertPolygon
= false;
547 bool bInvertNormals
= false;
555 bInvertNormals
= true;
556 aStripeBottom
= Stripe( aBottomP1
, aBottomP4
, aBottomP3
, aBottomP2
);
560 bInvertPolygon
= true;
562 aStripeBottom
= Stripe( aBottomP2
, aBottomP3
, aBottomP4
, aBottomP1
);
570 bInvertPolygon
= true;
572 aStripeBottom
= Stripe( aBottomP2
, aBottomP3
, aBottomP4
, aBottomP1
);
577 bInvertNormals
= true;
578 aStripeBottom
= Stripe( aBottomP4
, aBottomP3
, aBottomP2
, aBottomP1
);
581 aStripeBottom
.InvertNormal(true);
583 Stripe
aStripe1( aTopP2
, aTopP1
, aBottomP1
, aBottomP2
);
584 Stripe
aStripe2( aTopP3
, aTopP2
, aBottomP2
, aBottomP3
);
585 Stripe
aStripe3( aTopP4
, aTopP3
, aBottomP3
, aBottomP4
);
586 Stripe
aStripe4( aTopP1
, aTopP4
, aBottomP4
, aBottomP1
);
590 aStripe1
= Stripe( aBottomP1
, aTopP1
, aTopP2
, aBottomP2
);
591 aStripe2
= Stripe( aBottomP2
, aTopP2
, aTopP3
, aBottomP3
);
592 aStripe3
= Stripe( aBottomP3
, aTopP3
, aTopP4
, aBottomP4
);
593 aStripe4
= Stripe( aBottomP4
, aTopP4
, aTopP1
, aBottomP1
);
596 Stripe
aNormalsStripe1( aNormalsTopP1
, aNormalsBottomP1
, aNormalsBottomP2
, aNormalsTopP2
);
597 Stripe
aNormalsStripe2( aNormalsTopP2
, aNormalsBottomP2
, aNormalsBottomP3
, aNormalsTopP3
);
598 Stripe
aNormalsStripe3( aNormalsTopP3
, aNormalsBottomP3
, aNormalsBottomP4
, aNormalsTopP4
);
599 Stripe
aNormalsStripe4( aNormalsTopP4
, aNormalsBottomP4
, aNormalsBottomP1
, aNormalsTopP1
);
603 aNormalsStripe1
= Stripe( aNormalsTopP2
, aNormalsBottomP2
, aNormalsBottomP1
, aNormalsTopP1
);
604 aNormalsStripe2
= Stripe( aNormalsTopP3
, aNormalsBottomP3
, aNormalsBottomP2
, aNormalsTopP2
);
605 aNormalsStripe3
= Stripe( aNormalsTopP4
, aNormalsBottomP4
, aNormalsBottomP3
, aNormalsTopP3
);
606 aNormalsStripe4
= Stripe( aNormalsTopP1
, aNormalsBottomP1
, aNormalsBottomP4
, aNormalsTopP4
);
609 aStripe1
.SetManualNormal( aNormalsStripe1
.getNormal() );
610 aStripe2
.SetManualNormal( aNormalsStripe2
.getNormal() );
611 aStripe3
.SetManualNormal( aNormalsStripe3
.getNormal() );
612 aStripe4
.SetManualNormal( aNormalsStripe4
.getNormal() );
614 const bool bFlatNormals
= false;
615 ShapeFactory::createStripe( xGroup
, aStripe1
, xSourceProp
, rPropertyNameMap
, bDoubleSided
, nRotatedTexture
, bFlatNormals
);
616 ShapeFactory::createStripe( xGroup
, aStripe2
, xSourceProp
, rPropertyNameMap
, bDoubleSided
, nRotatedTexture
, bFlatNormals
);
617 ShapeFactory::createStripe( xGroup
, aStripe3
, xSourceProp
, rPropertyNameMap
, bDoubleSided
, nRotatedTexture
, bFlatNormals
);
618 ShapeFactory::createStripe( xGroup
, aStripe4
, xSourceProp
, rPropertyNameMap
, bDoubleSided
, nRotatedTexture
, bFlatNormals
);
619 ShapeFactory::createStripe( xGroup
, aStripeBottom
, xSourceProp
, rPropertyNameMap
, bDoubleSided
, nRotatedTexture
, bFlatNormals
);
621 return Reference
< drawing::XShape
>( xGroup
, uno::UNO_QUERY
);
624 uno::Reference
<drawing::XShape
>
625 ShapeFactory::createCone(
626 const uno::Reference
<drawing::XShapes
>& xTarget
627 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
628 , double fTopHeight
, sal_Int32 nRotateZAngleHundredthDegree
)
630 return impl_createConeOrCylinder( xTarget
, rPosition
, rSize
, fTopHeight
, nRotateZAngleHundredthDegree
, false );
633 uno::Reference
<drawing::XShape
>
634 ShapeFactory::impl_createConeOrCylinder(
635 const uno::Reference
<drawing::XShapes
>& xTarget
636 , const drawing::Position3D
& rPosition
, const drawing::Direction3D
& rSize
637 , double fTopHeight
, sal_Int32 nRotateZAngleHundredthDegree
644 uno::Reference
< drawing::XShape
> xShape(
645 m_xShapeFactory
->createInstance(
646 "com.sun.star.drawing.Shape3DLatheObject" ), uno::UNO_QUERY
);
647 xTarget
->add(xShape
);
649 double fWidth
= rSize
.DirectionX
/2.0; //The depth will be corrected within Matrix
650 double fRadius
= fWidth
; //!!!!!!!! problem in drawing layer: rotation object calculates wrong needed size -> wrong camera (it's a problem with bounding boxes)
651 double fHeight
= rSize
.DirectionY
;
654 uno::Reference
<beans::XMultiPropertySet
> xMultiPropertySet(xShape
, uno::UNO_QUERY
);
655 OSL_ENSURE(xMultiPropertySet
.is(), "created shape offers no XMultiPropertySet");
656 if (xMultiPropertySet
.is())
661 sal_Int32 nVerticalSegmentCount
= 0;
662 uno::Any aPPolygon
= bCylinder
663 ? createPolyPolygon_Cylinder(fHeight
, fRadius
, nVerticalSegmentCount
)
664 : createPolyPolygon_Cone(fHeight
, fRadius
, fTopHeight
, nVerticalSegmentCount
);
666 //Matrix for position
667 basegfx::B3DHomMatrix aHomMatrix
;
668 if (nRotateZAngleHundredthDegree
!= 0)
669 aHomMatrix
.rotate(0.0,0.0,-nRotateZAngleHundredthDegree
/18000.00*F_PI
);
670 //stretch the symmetric objects to given depth
671 aHomMatrix
.scale(1.0,1.0,rSize
.DirectionZ
/rSize
.DirectionX
);
672 aHomMatrix
.translate(rPosition
.PositionX
, rPosition
.PositionY
, rPosition
.PositionZ
);
674 uno::Sequence
<OUString
> aPropertyNames
{
675 UNO_NAME_3D_PERCENT_DIAGONAL
,
676 UNO_NAME_3D_POLYPOLYGON3D
,
677 UNO_NAME_3D_TRANSFORM_MATRIX
,
678 UNO_NAME_3D_HORZ_SEGS
,
679 UNO_NAME_3D_VERT_SEGS
,
680 UNO_NAME_3D_REDUCED_LINE_GEOMETRY
683 uno::Sequence
<uno::Any
> aPropertyValues
{
684 uno::Any(sal_Int16(5)), // PercentDiagonal
685 aPPolygon
, // Polygon
686 uno::Any(B3DHomMatrixToHomogenMatrix(aHomMatrix
)), // Matrix
687 uno::Any(CHART_3DOBJECT_SEGMENTCOUNT
), // Horizontal Segments
688 uno::Any(nVerticalSegmentCount
), // Vertical Segments
689 uno::Any(true) // Reduced lines
692 xMultiPropertySet
->setPropertyValues(aPropertyNames
, aPropertyValues
);
694 catch( const uno::Exception
& )
696 TOOLS_WARN_EXCEPTION("chart2", "" );
702 static void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords
& rReturn
, const drawing::PolyPolygonBezierCoords
& rAdd
, bool bAppendInverse
)
704 if(!rAdd
.Coordinates
.hasElements())
706 sal_Int32 nAddCount
= rAdd
.Coordinates
[0].getLength();
710 sal_Int32 nOldCount
= rReturn
.Coordinates
[0].getLength();
712 rReturn
.Coordinates
[0].realloc(nOldCount
+nAddCount
+1);
713 rReturn
.Flags
[0].realloc(nOldCount
+nAddCount
+1);
715 for(sal_Int32 nN
=0;nN
<nAddCount
; nN
++ )
717 sal_Int32 nAdd
= bAppendInverse
? (nAddCount
-1-nN
) : nN
;
718 rReturn
.Coordinates
[0][nOldCount
+nN
] = rAdd
.Coordinates
[0][nAdd
];
719 rReturn
.Flags
[0][nOldCount
+nN
] = rAdd
.Flags
[0][nAdd
];
723 rReturn
.Coordinates
[0][nOldCount
+nAddCount
] = rReturn
.Coordinates
[0][0];
724 rReturn
.Flags
[0][nOldCount
+nAddCount
] = rReturn
.Flags
[0][0];
727 static drawing::PolyPolygonBezierCoords
getCircularArcBezierCoords(
728 double fStartAngleRadian
, double fWidthAngleRadian
, double fUnitRadius
729 , const ::basegfx::B2DHomMatrix
& rTransformationFromUnitCircle
730 , const double fAngleSubdivisionRadian
)
732 //at least one polygon is created using two normal and two control points
733 //if the angle is larger it is separated into multiple sub angles
735 drawing::PolyPolygonBezierCoords aReturn
;
736 sal_Int32 nSegmentCount
= static_cast< sal_Int32
>( fWidthAngleRadian
/fAngleSubdivisionRadian
);
737 if( fWidthAngleRadian
> fAngleSubdivisionRadian
*nSegmentCount
)
740 double fFirstSegmentAngle
= fAngleSubdivisionRadian
;
741 double fLastSegmentAngle
= fAngleSubdivisionRadian
;
744 fFirstSegmentAngle
= fWidthAngleRadian
;
745 fLastSegmentAngle
= 0.0;
749 double fFirstAngleOnSubDevision
= (static_cast<sal_Int32
>(fStartAngleRadian
/fAngleSubdivisionRadian
)+1)*fAngleSubdivisionRadian
;
750 if( !::rtl::math::approxEqual( fStartAngleRadian
, fFirstAngleOnSubDevision
) )
751 fFirstSegmentAngle
= fFirstAngleOnSubDevision
-fStartAngleRadian
;
755 fLastSegmentAngle
= fWidthAngleRadian
-fFirstSegmentAngle
-fAngleSubdivisionRadian
*(nSegmentCount
-2);
756 if( fLastSegmentAngle
<0 )
758 if( fLastSegmentAngle
>fAngleSubdivisionRadian
)
760 fLastSegmentAngle
-=fAngleSubdivisionRadian
;
766 sal_Int32 nPointCount
= 1 + 3*nSegmentCount
; //first point of next segment equals last point of former segment
768 aReturn
.Coordinates
= drawing::PointSequenceSequence(1);
769 aReturn
.Flags
= drawing::FlagSequenceSequence(1);
771 drawing::PointSequence
aPoints(nPointCount
);
772 drawing::FlagSequence
aFlags(nPointCount
);
774 //!! applying matrix to vector does ignore translation, so it is important to use a B2DPoint here instead of B2DVector
775 ::basegfx::B2DPoint P0
,P1
,P2
,P3
;
778 double fCurrentRotateAngle
= fStartAngleRadian
;
779 for(sal_Int32 nSegment
=0; nSegment
<nSegmentCount
; nSegment
++)
781 double fCurrentSegmentAngle
= fAngleSubdivisionRadian
;
782 if(nSegment
==0)//first segment gets only a smaller peace until the next subdevision
783 fCurrentSegmentAngle
= fFirstSegmentAngle
;
784 else if(nSegment
==(nSegmentCount
-1)) //the last segment gets the rest angle that does not fit into equal pieces
785 fCurrentSegmentAngle
= fLastSegmentAngle
;
787 //first create untransformed points for a unit circle arc:
788 const double fCos
= cos(fCurrentSegmentAngle
/2.0);
789 const double fSin
= sin(fCurrentSegmentAngle
/2.0);
795 P1
.setX((4.0-fCos
)/3.0);
797 P1
.setY((1.0-fCos
)*(fCos
-3.0)/(3.0*fSin
));
799 //transform thus startangle equals NULL
800 ::basegfx::B2DHomMatrix aStart
;
801 aStart
.rotate(fCurrentSegmentAngle
/2.0 + fCurrentRotateAngle
);
802 fCurrentRotateAngle
+=fCurrentSegmentAngle
;
804 aStart
.scale( fUnitRadius
, fUnitRadius
);
806 //apply given transformation to get final points
807 P0
= rTransformationFromUnitCircle
*(aStart
*P0
);
808 P1
= rTransformationFromUnitCircle
*(aStart
*P1
);
809 P2
= rTransformationFromUnitCircle
*(aStart
*P2
);
810 P3
= rTransformationFromUnitCircle
*(aStart
*P3
);
812 aPoints
[nPoint
].X
= static_cast< sal_Int32
>( P0
.getX());
813 aPoints
[nPoint
].Y
= static_cast< sal_Int32
>( P0
.getY());
814 aFlags
[nPoint
++] = drawing::PolygonFlags_NORMAL
;
816 aPoints
[nPoint
].X
= static_cast< sal_Int32
>( P1
.getX());
817 aPoints
[nPoint
].Y
= static_cast< sal_Int32
>( P1
.getY());
818 aFlags
[nPoint
++] = drawing::PolygonFlags_CONTROL
;
820 aPoints
[nPoint
].X
= static_cast< sal_Int32
>( P2
.getX());
821 aPoints
[nPoint
].Y
= static_cast< sal_Int32
>( P2
.getY());
822 aFlags
[nPoint
++] = drawing::PolygonFlags_CONTROL
;
824 if(nSegment
==(nSegmentCount
-1))
826 aPoints
[nPoint
].X
= static_cast< sal_Int32
>( P3
.getX());
827 aPoints
[nPoint
].Y
= static_cast< sal_Int32
>( P3
.getY());
828 aFlags
[nPoint
++] = drawing::PolygonFlags_NORMAL
;
832 aReturn
.Coordinates
[0] = aPoints
;
833 aReturn
.Flags
[0] = aFlags
;
838 static drawing::PolyPolygonBezierCoords
getRingBezierCoords(
839 double fUnitCircleInnerRadius
840 , double fUnitCircleOuterRadius
841 , double fStartAngleRadian
, double fWidthAngleRadian
842 , const ::basegfx::B2DHomMatrix
& aTransformationFromUnitCircle
843 , const double fAngleSubdivisionRadian
)
845 drawing::PolyPolygonBezierCoords aReturn
;
847 aReturn
.Coordinates
= drawing::PointSequenceSequence(1);
848 aReturn
.Flags
= drawing::FlagSequenceSequence(1);
850 drawing::PolyPolygonBezierCoords aOuterArc
= getCircularArcBezierCoords(
851 fStartAngleRadian
, fWidthAngleRadian
, fUnitCircleOuterRadius
, aTransformationFromUnitCircle
, fAngleSubdivisionRadian
);
852 aReturn
.Coordinates
[0] = aOuterArc
.Coordinates
[0];
853 aReturn
.Flags
[0] = aOuterArc
.Flags
[0];
855 drawing::PolyPolygonBezierCoords aInnerArc
= getCircularArcBezierCoords(
856 fStartAngleRadian
, fWidthAngleRadian
, fUnitCircleInnerRadius
, aTransformationFromUnitCircle
, fAngleSubdivisionRadian
);
857 appendAndCloseBezierCoords( aReturn
, aInnerArc
, true );
862 uno::Reference
< drawing::XShape
>
863 ShapeFactory::createPieSegment2D(
864 const uno::Reference
< drawing::XShapes
>& xTarget
865 , double fUnitCircleStartAngleDegree
, double fUnitCircleWidthAngleDegree
866 , double fUnitCircleInnerRadius
, double fUnitCircleOuterRadius
867 , const drawing::Direction3D
& rOffset
868 , const drawing::HomogenMatrix
& rUnitCircleToScene
)
873 // tdf#123504: both 0 and 360 are valid and different values here!
874 while (fUnitCircleWidthAngleDegree
> 360)
875 fUnitCircleWidthAngleDegree
-= 360.0;
876 while (fUnitCircleWidthAngleDegree
< 0)
877 fUnitCircleWidthAngleDegree
+= 360.0;
880 uno::Reference
< drawing::XShape
> xShape(
881 m_xShapeFactory
->createInstance(
882 "com.sun.star.drawing.ClosedBezierShape" ), uno::UNO_QUERY
);
883 xTarget
->add(xShape
); //need to add the shape before setting of properties
886 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
887 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
892 ::basegfx::B2DHomMatrix
aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene
) ) );
893 aTransformationFromUnitCircle
.translate(rOffset
.DirectionX
,rOffset
.DirectionY
);
895 const double fAngleSubdivisionRadian
= F_PI
/10.0;
897 drawing::PolyPolygonBezierCoords aCoords
898 = getRingBezierCoords(fUnitCircleInnerRadius
, fUnitCircleOuterRadius
,
899 basegfx::deg2rad(fUnitCircleStartAngleDegree
),
900 basegfx::deg2rad(fUnitCircleWidthAngleDegree
),
901 aTransformationFromUnitCircle
, fAngleSubdivisionRadian
);
903 xProp
->setPropertyValue( "PolyPolygonBezier", uno::Any( aCoords
) );
905 catch( const uno::Exception
& )
907 TOOLS_WARN_EXCEPTION("chart2", "" );
914 uno::Reference
< drawing::XShape
>
915 ShapeFactory::createPieSegment(
916 const uno::Reference
< drawing::XShapes
>& xTarget
917 , double fUnitCircleStartAngleDegree
, double fUnitCircleWidthAngleDegree
918 , double fUnitCircleInnerRadius
, double fUnitCircleOuterRadius
919 , const drawing::Direction3D
& rOffset
920 , const drawing::HomogenMatrix
& rUnitCircleToScene
926 // tdf#123504: both 0 and 360 are valid and different values here!
927 while (fUnitCircleWidthAngleDegree
> 360)
928 fUnitCircleWidthAngleDegree
-= 360.0;
929 while (fUnitCircleWidthAngleDegree
< 0)
930 fUnitCircleWidthAngleDegree
+= 360.0;
933 uno::Reference
< drawing::XShape
> xShape(
934 m_xShapeFactory
->createInstance(
935 "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY
);
936 xTarget
->add(xShape
); //need to add the shape before setting of properties
939 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
940 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
945 ::basegfx::B2DHomMatrix
aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene
) ) );
946 aTransformationFromUnitCircle
.translate(rOffset
.DirectionX
,rOffset
.DirectionY
);
948 const double fAngleSubdivisionRadian
= F_PI
/32.0;
950 drawing::PolyPolygonBezierCoords aCoords
951 = getRingBezierCoords(fUnitCircleInnerRadius
, fUnitCircleOuterRadius
,
952 basegfx::deg2rad(fUnitCircleStartAngleDegree
),
953 basegfx::deg2rad(fUnitCircleWidthAngleDegree
),
954 aTransformationFromUnitCircle
, fAngleSubdivisionRadian
);
957 xProp
->setPropertyValue( UNO_NAME_3D_EXTRUDE_DEPTH
958 , uno::Any(static_cast<sal_Int32
>(fDepth
)) );
961 xProp
->setPropertyValue( UNO_NAME_3D_PERCENT_DIAGONAL
962 , uno::Any( sal_Int16(0) ) );
965 drawing::PolyPolygonShape3D
aPoly( BezierToPoly(aCoords
) );
966 ShapeFactory::closePolygon( aPoly
);
967 xProp
->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
968 , uno::Any( aPoly
) );
971 xProp
->setPropertyValue( UNO_NAME_3D_DOUBLE_SIDED
972 , uno::Any( true ) );
975 xProp
->setPropertyValue( UNO_NAME_3D_REDUCED_LINE_GEOMETRY
976 , uno::Any( true ) );
978 //TextureProjectionMode
979 xProp
->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
980 , uno::Any( drawing::TextureProjectionMode_OBJECTSPECIFIC
) );
982 //TextureProjectionMode
983 xProp
->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_X
984 , uno::Any( drawing::TextureProjectionMode_PARALLEL
) );
985 xProp
->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
986 , uno::Any( drawing::TextureProjectionMode_OBJECTSPECIFIC
) );
988 catch( const uno::Exception
& )
990 TOOLS_WARN_EXCEPTION("chart2", "" );
996 uno::Reference
< drawing::XShape
>
997 ShapeFactory::createStripe( const uno::Reference
< drawing::XShapes
>& xTarget
998 , const Stripe
& rStripe
999 , const uno::Reference
< beans::XPropertySet
>& xSourceProp
1000 , const tPropertyNameMap
& rPropertyNameMap
1002 , short nRotatedTexture
1003 , bool bFlatNormals
)
1009 uno::Reference
< drawing::XShape
> xShape(
1010 m_xShapeFactory
->createInstance(
1011 "com.sun.star.drawing.Shape3DPolygonObject" ), uno::UNO_QUERY
);
1012 xTarget
->add(xShape
);
1015 uno::Reference
<beans::XMultiPropertySet
> xMultiPropertySet(xShape
, uno::UNO_QUERY
);
1016 OSL_ENSURE(xMultiPropertySet
.is(), "created shape offers no XMultiPropertySet");
1017 if (xMultiPropertySet
.is())
1021 uno::Sequence
<OUString
> aPropertyNames
{
1022 UNO_NAME_3D_POLYPOLYGON3D
,
1023 UNO_NAME_3D_TEXTUREPOLYGON3D
,
1024 UNO_NAME_3D_NORMALSPOLYGON3D
,
1025 UNO_NAME_3D_LINEONLY
,
1026 UNO_NAME_3D_DOUBLE_SIDED
1029 uno::Sequence
<uno::Any
> aPropertyValues
{
1030 rStripe
.getPolyPolygonShape3D(), // Polygon
1031 Stripe::getTexturePolygon(nRotatedTexture
), // TexturePolygon
1032 rStripe
.getNormalsPolygon(), // Normals Polygon
1033 uno::Any(false), // LineOnly
1034 uno::Any(bDoubleSided
) // DoubleSided
1039 lcl_addProperty(aPropertyNames
, aPropertyValues
,
1040 UNO_NAME_3D_NORMALS_KIND
, uno::Any(drawing::NormalsKind_FLAT
));
1042 xMultiPropertySet
->setPropertyValues(aPropertyNames
, aPropertyValues
);
1044 uno::Reference
<beans::XPropertySet
> xPropertySet(xShape
, uno::UNO_QUERY
);
1045 if (xSourceProp
.is() && xPropertySet
.is())
1047 PropertyMapper::setMappedProperties(xPropertySet
, xSourceProp
, rPropertyNameMap
);
1050 catch( const uno::Exception
& )
1052 TOOLS_WARN_EXCEPTION("chart2", "" );
1058 uno::Reference
< drawing::XShape
>
1059 ShapeFactory::createArea3D( const uno::Reference
< drawing::XShapes
>& xTarget
1060 , const drawing::PolyPolygonShape3D
& rPolyPolygon
1066 if( !rPolyPolygon
.SequenceX
.hasElements())
1070 uno::Reference
< drawing::XShape
> xShape(
1071 m_xShapeFactory
->createInstance(
1072 "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY
);
1073 xTarget
->add(xShape
);
1076 uno::Reference
<beans::XMultiPropertySet
> xMultiPropertySet(xShape
, uno::UNO_QUERY
);
1077 OSL_ENSURE(xMultiPropertySet
.is(), "created shape offers no XMultiPropertySet");
1078 if (xMultiPropertySet
.is())
1082 uno::Sequence
<OUString
> aPropertyNames
{
1083 UNO_NAME_3D_EXTRUDE_DEPTH
,
1084 UNO_NAME_3D_PERCENT_DIAGONAL
,
1085 UNO_NAME_3D_POLYPOLYGON3D
,
1086 UNO_NAME_3D_DOUBLE_SIDED
,
1089 uno::Sequence
<uno::Any
> aPropertyValues
{
1090 uno::Any(sal_Int32(fDepth
)), // depth
1091 uno::Any(sal_Int16(0)), // PercentDiagonal
1092 uno::Any(rPolyPolygon
), // Polygon
1093 uno::Any(true) // DoubleSided
1096 //the z component of the polygon is now ignored by the drawing layer,
1097 //so we need to translate the object via transformation matrix
1099 //Matrix for position
1100 if (rPolyPolygon
.SequenceZ
.hasElements()&& rPolyPolygon
.SequenceZ
[0].hasElements())
1102 basegfx::B3DHomMatrix aM
;
1103 aM
.translate(0, 0, rPolyPolygon
.SequenceZ
[0][0]);
1104 drawing::HomogenMatrix aHM
= B3DHomMatrixToHomogenMatrix(aM
);
1105 lcl_addProperty(aPropertyNames
, aPropertyValues
, UNO_NAME_3D_TRANSFORM_MATRIX
, uno::Any(aHM
));
1107 xMultiPropertySet
->setPropertyValues(aPropertyNames
, aPropertyValues
);
1109 catch( const uno::Exception
& )
1111 TOOLS_WARN_EXCEPTION("chart2", "" );
1117 uno::Reference
< drawing::XShape
>
1118 ShapeFactory::createArea2D( const uno::Reference
< drawing::XShapes
>& xTarget
1119 , const drawing::PolyPolygonShape3D
& rPolyPolygon
)
1125 uno::Reference
< drawing::XShape
> xShape(
1126 m_xShapeFactory
->createInstance(
1127 "com.sun.star.drawing.PolyPolygonShape" ), uno::UNO_QUERY
);
1128 xTarget
->add(xShape
);
1131 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1132 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
1137 //UNO_NAME_POLYGON "Polygon" drawing::PointSequence*
1138 drawing::PointSequenceSequence
aPoints( PolyToPointSequence(rPolyPolygon
) );
1141 xProp
->setPropertyValue( UNO_NAME_POLYPOLYGON
1142 , uno::Any( aPoints
) );
1145 //an area should always be behind other shapes
1146 xProp
->setPropertyValue( UNO_NAME_MISC_OBJ_ZORDER
1147 , uno::Any( sal_Int32(0) ) );
1149 catch( const uno::Exception
& )
1151 TOOLS_WARN_EXCEPTION("chart2", "" );
1157 static drawing::PolyPolygonShape3D
createPolyPolygon_Symbol( const drawing::Position3D
& rPos
1158 , const drawing::Direction3D
& rSize
1159 , sal_Int32 nStandardSymbol
)
1161 if(nStandardSymbol
<0)
1162 nStandardSymbol
*=-1;
1163 nStandardSymbol
= nStandardSymbol
%ShapeFactory::getSymbolCount();
1164 SymbolEnum eSymbolType
=static_cast<SymbolEnum
>(nStandardSymbol
);
1166 const double& fX
= rPos
.PositionX
;
1167 const double& fY
= rPos
.PositionY
;
1169 const double fWidthH
= rSize
.DirectionX
/2.0; //fWidthH stands for Half Width
1170 const double fHeightH
= rSize
.DirectionY
/2.0; //fHeightH stands for Half Height
1172 const sal_Int32 nQuarterCount
= 35; // points inside a quadrant, used in case circle
1174 sal_Int32 nPointCount
= 4; //all arrow symbols only need 4 points
1175 switch( eSymbolType
)
1178 case Symbol_Diamond
:
1180 case Symbol_Sandglass
:
1181 case Symbol_HorizontalBar
:
1182 case Symbol_VerticalBar
:
1194 case Symbol_Asterisk
:
1198 nPointCount
= 5 + 4 * nQuarterCount
;
1204 drawing::PolyPolygonShape3D aPP
;
1206 aPP
.SequenceX
.realloc(1);
1207 aPP
.SequenceY
.realloc(1);
1208 aPP
.SequenceZ
.realloc(1);
1210 drawing::DoubleSequence
* pOuterSequenceX
= aPP
.SequenceX
.getArray();
1211 drawing::DoubleSequence
* pOuterSequenceY
= aPP
.SequenceY
.getArray();
1212 drawing::DoubleSequence
* pOuterSequenceZ
= aPP
.SequenceZ
.getArray();
1214 pOuterSequenceX
->realloc(nPointCount
);
1215 pOuterSequenceY
->realloc(nPointCount
);
1216 pOuterSequenceZ
->realloc(nPointCount
);
1218 double* pInnerSequenceX
= pOuterSequenceX
->getArray();
1219 double* pInnerSequenceY
= pOuterSequenceY
->getArray();
1220 double* pInnerSequenceZ
= pOuterSequenceZ
->getArray();
1222 for(sal_Int32 nN
= nPointCount
; nN
--;)
1223 *pInnerSequenceZ
++ = 0.0;
1229 *pInnerSequenceX
++ = fX
-fWidthH
;
1230 *pInnerSequenceY
++ = fY
-fHeightH
;
1232 *pInnerSequenceX
++ = fX
-fWidthH
;
1233 *pInnerSequenceY
++ = fY
+fHeightH
;
1235 *pInnerSequenceX
++ = fX
+fWidthH
;
1236 *pInnerSequenceY
++ = fY
+fHeightH
;
1238 *pInnerSequenceX
++ = fX
+fWidthH
;
1239 *pInnerSequenceY
++ = fY
-fHeightH
;
1241 *pInnerSequenceX
++ = fX
-fWidthH
;
1242 *pInnerSequenceY
++ = fY
-fHeightH
;
1245 case Symbol_UpArrow
:
1247 *pInnerSequenceX
++ = fX
-fWidthH
;
1248 *pInnerSequenceY
++ = fY
+fHeightH
;
1250 *pInnerSequenceX
++ = fX
+fWidthH
;
1251 *pInnerSequenceY
++ = fY
+fHeightH
;
1253 *pInnerSequenceX
++ = fX
;
1254 *pInnerSequenceY
++ = fY
-fHeightH
;
1256 *pInnerSequenceX
++ = fX
-fWidthH
;
1257 *pInnerSequenceY
++ = fY
+fHeightH
;
1260 case Symbol_DownArrow
:
1262 *pInnerSequenceX
++ = fX
-fWidthH
;
1263 *pInnerSequenceY
++ = fY
-fHeightH
;
1265 *pInnerSequenceX
++ = fX
;
1266 *pInnerSequenceY
++ = fY
+fHeightH
;
1268 *pInnerSequenceX
++ = fX
+fWidthH
;
1269 *pInnerSequenceY
++ = fY
-fHeightH
;
1271 *pInnerSequenceX
++ = fX
-fWidthH
;
1272 *pInnerSequenceY
++ = fY
-fHeightH
;
1275 case Symbol_RightArrow
:
1277 *pInnerSequenceX
++ = fX
-fWidthH
;
1278 *pInnerSequenceY
++ = fY
-fHeightH
;
1280 *pInnerSequenceX
++ = fX
-fWidthH
;
1281 *pInnerSequenceY
++ = fY
+fHeightH
;
1283 *pInnerSequenceX
++ = fX
+fWidthH
;
1284 *pInnerSequenceY
++ = fY
;
1286 *pInnerSequenceX
++ = fX
-fWidthH
;
1287 *pInnerSequenceY
++ = fY
-fHeightH
;
1290 case Symbol_LeftArrow
:
1292 *pInnerSequenceX
++ = fX
-fWidthH
;
1293 *pInnerSequenceY
++ = fY
;
1295 *pInnerSequenceX
++ = fX
+fWidthH
;
1296 *pInnerSequenceY
++ = fY
+fHeightH
;
1298 *pInnerSequenceX
++ = fX
+fWidthH
;
1299 *pInnerSequenceY
++ = fY
-fHeightH
;
1301 *pInnerSequenceX
++ = fX
-fWidthH
;
1302 *pInnerSequenceY
++ = fY
;
1307 *pInnerSequenceX
++ = fX
-fWidthH
;
1308 *pInnerSequenceY
++ = fY
-fHeightH
;
1310 *pInnerSequenceX
++ = fX
-fWidthH
;
1311 *pInnerSequenceY
++ = fY
+fHeightH
;
1313 *pInnerSequenceX
++ = fX
+fWidthH
;
1314 *pInnerSequenceY
++ = fY
-fHeightH
;
1316 *pInnerSequenceX
++ = fX
+fWidthH
;
1317 *pInnerSequenceY
++ = fY
+fHeightH
;
1319 *pInnerSequenceX
++ = fX
-fWidthH
;
1320 *pInnerSequenceY
++ = fY
-fHeightH
;
1323 case Symbol_Sandglass
:
1325 *pInnerSequenceX
++ = fX
-fWidthH
;
1326 *pInnerSequenceY
++ = fY
+fHeightH
;
1328 *pInnerSequenceX
++ = fX
+fWidthH
;
1329 *pInnerSequenceY
++ = fY
+fHeightH
;
1331 *pInnerSequenceX
++ = fX
-fWidthH
;
1332 *pInnerSequenceY
++ = fY
-fHeightH
;
1334 *pInnerSequenceX
++ = fX
+fWidthH
;
1335 *pInnerSequenceY
++ = fY
-fHeightH
;
1337 *pInnerSequenceX
++ = fX
-fWidthH
;
1338 *pInnerSequenceY
++ = fY
+fHeightH
;
1341 case Symbol_Diamond
:
1343 *pInnerSequenceX
++ = fX
-fWidthH
;
1344 *pInnerSequenceY
++ = fY
;
1346 *pInnerSequenceX
++ = fX
;
1347 *pInnerSequenceY
++ = fY
+fHeightH
;
1349 *pInnerSequenceX
++ = fX
+fWidthH
;
1350 *pInnerSequenceY
++ = fY
;
1352 *pInnerSequenceX
++ = fX
;
1353 *pInnerSequenceY
++ = fY
-fHeightH
;
1355 *pInnerSequenceX
++ = fX
-fWidthH
;
1356 *pInnerSequenceY
++ = fY
;
1359 case Symbol_HorizontalBar
:
1361 *pInnerSequenceX
++ = fX
-fWidthH
;
1362 *pInnerSequenceY
++ = fY
-0.2*fHeightH
;
1364 *pInnerSequenceX
++ = fX
+fWidthH
;
1365 *pInnerSequenceY
++ = fY
-0.2*fHeightH
;
1367 *pInnerSequenceX
++ = fX
+fWidthH
;
1368 *pInnerSequenceY
++ = fY
+0.2*fHeightH
;
1370 *pInnerSequenceX
++ = fX
-fWidthH
;
1371 *pInnerSequenceY
++ = fY
+0.2*fHeightH
;
1373 *pInnerSequenceX
++ = fX
-fWidthH
;
1374 *pInnerSequenceY
++ = fY
-0.2*fHeightH
;
1377 case Symbol_VerticalBar
:
1379 *pInnerSequenceX
++ = fX
-0.2*fWidthH
;
1380 *pInnerSequenceY
++ = fY
-fHeightH
;
1382 *pInnerSequenceX
++ = fX
+0.2*fWidthH
;
1383 *pInnerSequenceY
++ = fY
-fHeightH
;
1385 *pInnerSequenceX
++ = fX
+0.2*fWidthH
;
1386 *pInnerSequenceY
++ = fY
+fHeightH
;
1388 *pInnerSequenceX
++ = fX
-0.2*fWidthH
;
1389 *pInnerSequenceY
++ = fY
+fHeightH
;
1391 *pInnerSequenceX
++ = fX
-0.2*fWidthH
;
1392 *pInnerSequenceY
++ = fY
-fHeightH
;
1398 double fOmega
= 1.5707963267948966192 / (nQuarterCount
+ 1.0);
1399 // one point in the middle of each edge to get full size bounding rectangle
1400 *pInnerSequenceX
++ = fX
+ fWidthH
;
1401 *pInnerSequenceY
++ = fY
;
1403 for (sal_Int32 i
= 1; i
<= nQuarterCount
; ++i
)
1405 *pInnerSequenceX
++ = fX
+ fWidthH
* cos( i
* fOmega
);
1406 *pInnerSequenceY
++ = fY
- fHeightH
* sin( i
* fOmega
);
1409 *pInnerSequenceX
++ = fX
;
1410 *pInnerSequenceY
++ = fY
- fHeightH
;
1411 for (sal_Int32 i
= 1; i
<= nQuarterCount
; ++i
)
1413 *pInnerSequenceX
++ = fX
- fWidthH
* sin( i
* fOmega
);
1414 *pInnerSequenceY
++ = fY
- fHeightH
* cos( i
* fOmega
);
1417 *pInnerSequenceX
++ = fX
- fWidthH
;
1418 *pInnerSequenceY
++ = fY
;
1419 for (sal_Int32 i
= 1; i
<= nQuarterCount
; ++i
)
1421 *pInnerSequenceX
++ = fX
- fWidthH
* cos( i
* fOmega
);
1422 *pInnerSequenceY
++ = fY
+ fHeightH
* sin( i
* fOmega
);
1425 *pInnerSequenceX
++ = fX
;
1426 *pInnerSequenceY
++ = fY
+ fHeightH
;
1427 for (sal_Int32 i
= 1; i
<= nQuarterCount
; ++i
)
1429 *pInnerSequenceX
++ = fX
+ fWidthH
* sin(i
* fOmega
);
1430 *pInnerSequenceY
++ = fY
+ fHeightH
* cos(i
* fOmega
);
1433 *pInnerSequenceX
++ = fX
+ fWidthH
;
1434 *pInnerSequenceY
++ = fY
;
1439 *pInnerSequenceX
++ = fX
;
1440 *pInnerSequenceY
++ = fY
-fHeightH
;
1442 *pInnerSequenceX
++ = fX
+0.2*fWidthH
;
1443 *pInnerSequenceY
++ = fY
-0.2*fHeightH
;
1445 *pInnerSequenceX
++ = fX
+fWidthH
;
1446 *pInnerSequenceY
++ = fY
;
1448 *pInnerSequenceX
++ = fX
+0.2*fWidthH
;
1449 *pInnerSequenceY
++ = fY
+0.2*fHeightH
;
1451 *pInnerSequenceX
++ = fX
;
1452 *pInnerSequenceY
++ = fY
+fHeightH
;
1454 *pInnerSequenceX
++ = fX
-0.2*fWidthH
;
1455 *pInnerSequenceY
++ = fY
+0.2*fHeightH
;
1457 *pInnerSequenceX
++ = fX
-fWidthH
;
1458 *pInnerSequenceY
++ = fY
;
1460 *pInnerSequenceX
++ = fX
-0.2*fWidthH
;
1461 *pInnerSequenceY
++ = fY
-0.2*fHeightH
;
1463 *pInnerSequenceX
++ = fX
;
1464 *pInnerSequenceY
++ = fY
-fHeightH
;
1469 const double fScaleX
= fWidthH
/ 128.0;
1470 const double fScaleY
= fHeightH
/ 128.0;
1471 const double fSmall
= sqrt(200.0);
1472 const double fLarge
= 128.0 - fSmall
;
1474 *pInnerSequenceX
++ = fX
;
1475 *pInnerSequenceY
++ = fY
- fScaleY
* fSmall
;
1477 *pInnerSequenceX
++ = fX
- fScaleX
* fLarge
;
1478 *pInnerSequenceY
++ = fY
- fHeightH
;
1480 *pInnerSequenceX
++ = fX
- fWidthH
;
1481 *pInnerSequenceY
++ = fY
- fScaleY
* fLarge
;
1483 *pInnerSequenceX
++ = fX
- fScaleX
* fSmall
;
1484 *pInnerSequenceY
++ = fY
;
1486 *pInnerSequenceX
++ = fX
- fWidthH
;
1487 *pInnerSequenceY
++ = fY
+ fScaleY
* fLarge
;
1489 *pInnerSequenceX
++ = fX
- fScaleX
* fLarge
;
1490 *pInnerSequenceY
++ = fY
+ fHeightH
;
1492 *pInnerSequenceX
++ = fX
;
1493 *pInnerSequenceY
++ = fY
+ fScaleY
* fSmall
;
1495 *pInnerSequenceX
++ = fX
+ fScaleX
* fLarge
;
1496 *pInnerSequenceY
++ = fY
+ fHeightH
;
1498 *pInnerSequenceX
++ = fX
+ fWidthH
;
1499 *pInnerSequenceY
++ = fY
+ fScaleY
* fLarge
;
1501 *pInnerSequenceX
++ = fX
+ fScaleX
* fSmall
;
1502 *pInnerSequenceY
++ = fY
;
1504 *pInnerSequenceX
++ = fX
+ fWidthH
;
1505 *pInnerSequenceY
++ = fY
- fScaleY
* fLarge
;
1507 *pInnerSequenceX
++ = fX
+ fScaleX
* fLarge
;
1508 *pInnerSequenceY
++ = fY
- fHeightH
;
1510 *pInnerSequenceX
++ = fX
;
1511 *pInnerSequenceY
++ = fY
- fScaleY
* fSmall
;
1517 const double fScaleX
= fWidthH
/ 128.0;
1518 const double fScaleY
= fHeightH
/ 128.0;
1519 const double fHalf
= 10.0; //half line width on 256 size square
1520 const double fdX
= fScaleX
* fHalf
;
1521 const double fdY
= fScaleY
* fHalf
;
1523 *pInnerSequenceX
++ = fX
-fdX
;
1524 *pInnerSequenceY
++ = fY
-fHeightH
;
1526 *pInnerSequenceX
++ = fX
-fdX
;
1527 *pInnerSequenceY
++ = fY
-fdY
;
1529 *pInnerSequenceX
++ = fX
-fWidthH
;
1530 *pInnerSequenceY
++ = fY
-fdY
;
1532 *pInnerSequenceX
++ = fX
-fWidthH
;
1533 *pInnerSequenceY
++ = fY
+fdY
;
1535 *pInnerSequenceX
++ = fX
-fdX
;
1536 *pInnerSequenceY
++ = fY
+fdY
;
1538 *pInnerSequenceX
++ = fX
-fdX
;
1539 *pInnerSequenceY
++ = fY
+fHeightH
;
1541 *pInnerSequenceX
++ = fX
+fdX
;
1542 *pInnerSequenceY
++ = fY
+fHeightH
;
1544 *pInnerSequenceX
++ = fX
+fdX
;
1545 *pInnerSequenceY
++ = fY
+fdY
;
1547 *pInnerSequenceX
++ = fX
+fWidthH
;
1548 *pInnerSequenceY
++ = fY
+fdY
;
1550 *pInnerSequenceX
++ = fX
+fWidthH
;
1551 *pInnerSequenceY
++ = fY
-fdY
;
1553 *pInnerSequenceX
++ = fX
+fdX
;
1554 *pInnerSequenceY
++ = fY
-fdY
;
1556 *pInnerSequenceX
++ = fX
+fdY
;
1557 *pInnerSequenceY
++ = fY
-fHeightH
;
1559 *pInnerSequenceX
++ = fX
-fdX
;
1560 *pInnerSequenceY
++ = fY
-fHeightH
;
1564 case Symbol_Asterisk
:
1566 const double fHalf
= 10.0; // half line width on 256 size square
1567 const double fTwoY
= fHalf
* sqrt(3.0);
1568 const double fFourY
= (128.0 - 2.0 * fHalf
) / sqrt(3.0);
1569 const double fThreeX
= 128.0 - fHalf
;
1570 const double fThreeY
= fHalf
* sqrt(3.0) + fFourY
;
1571 const double fFiveX
= 2.0 * fHalf
;
1573 const double fScaleX
= fWidthH
/ 128.0;
1574 const double fScaleY
= fHeightH
/ 128.0;
1577 *pInnerSequenceX
++ = fX
-fScaleX
* fHalf
;
1578 *pInnerSequenceY
++ = fY
-fHeightH
;
1580 *pInnerSequenceX
++ = fX
-fScaleX
* fHalf
;
1581 *pInnerSequenceY
++ = fY
-fScaleY
* fTwoY
;
1583 *pInnerSequenceX
++ = fX
-fScaleX
* fThreeX
;
1584 *pInnerSequenceY
++ = fY
-fScaleY
* fThreeY
;
1586 *pInnerSequenceX
++ = fX
-fWidthH
;
1587 *pInnerSequenceY
++ = fY
-fScaleY
* fFourY
;
1589 *pInnerSequenceX
++ = fX
-fScaleX
* fFiveX
;
1590 *pInnerSequenceY
++ = fY
;
1592 *pInnerSequenceX
++ = fX
-fWidthH
;
1593 *pInnerSequenceY
++ = fY
+fScaleY
* fFourY
;
1595 *pInnerSequenceX
++ = fX
-fScaleX
* fThreeX
;
1596 *pInnerSequenceY
++ = fY
+fScaleY
* fThreeY
;
1598 *pInnerSequenceX
++ = fX
-fScaleX
* fHalf
;
1599 *pInnerSequenceY
++ = fY
+fScaleY
* fTwoY
;
1601 *pInnerSequenceX
++ = fX
-fScaleX
* fHalf
;
1602 *pInnerSequenceY
++ = fY
+fHeightH
;
1604 *pInnerSequenceX
++ = fX
+fScaleX
* fHalf
;
1605 *pInnerSequenceY
++ = fY
+fHeightH
;
1607 *pInnerSequenceX
++ = fX
+fScaleX
* fHalf
;
1608 *pInnerSequenceY
++ = fY
+fScaleY
* fTwoY
;
1610 *pInnerSequenceX
++ = fX
+fScaleX
* fThreeX
;
1611 *pInnerSequenceY
++ = fY
+fScaleY
* fThreeY
;
1613 *pInnerSequenceX
++ = fX
+fWidthH
;
1614 *pInnerSequenceY
++ = fY
+fScaleY
* fFourY
;
1616 *pInnerSequenceX
++ = fX
+fScaleX
* fFiveX
;
1617 *pInnerSequenceY
++ = fY
;
1619 *pInnerSequenceX
++ = fX
+fWidthH
;
1620 *pInnerSequenceY
++ = fY
-fScaleY
* fFourY
;
1622 *pInnerSequenceX
++ = fX
+fScaleX
* fThreeX
;
1623 *pInnerSequenceY
++ = fY
-fScaleY
* fThreeY
;
1625 *pInnerSequenceX
++ = fX
+fScaleX
* fHalf
;
1626 *pInnerSequenceY
++ = fY
-fScaleY
* fTwoY
;
1628 *pInnerSequenceX
++ = fX
+fScaleX
* fHalf
;
1629 *pInnerSequenceY
++ = fY
-fHeightH
;
1631 *pInnerSequenceX
++ = fX
-fScaleX
* fHalf
;
1632 *pInnerSequenceY
++ = fY
-fHeightH
;
1635 default: //case Symbol_Square:
1637 *pInnerSequenceX
++ = fX
-fWidthH
;
1638 *pInnerSequenceY
++ = fY
-fHeightH
;
1640 *pInnerSequenceX
++ = fX
-fWidthH
;
1641 *pInnerSequenceY
++ = fY
+fHeightH
;
1643 *pInnerSequenceX
++ = fX
+fWidthH
;
1644 *pInnerSequenceY
++ = fY
+fHeightH
;
1646 *pInnerSequenceX
++ = fX
+fWidthH
;
1647 *pInnerSequenceY
++ = fY
-fHeightH
;
1649 *pInnerSequenceX
++ = fX
-fWidthH
;
1650 *pInnerSequenceY
++ = fY
-fHeightH
;
1658 uno::Reference
< drawing::XShape
>
1659 ShapeFactory::createSymbol2D(
1660 const uno::Reference
< drawing::XShapes
>& xTarget
1661 , const drawing::Position3D
& rPosition
1662 , const drawing::Direction3D
& rSize
1663 , sal_Int32 nStandardSymbol
1664 , sal_Int32 nBorderColor
1665 , sal_Int32 nFillColor
)
1671 uno::Reference
< drawing::XShape
> xShape(
1672 m_xShapeFactory
->createInstance(
1673 "com.sun.star.drawing.PolyPolygonShape" ), uno::UNO_QUERY
);
1674 xTarget
->add(xShape
);
1677 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1678 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
1683 drawing::PointSequenceSequence
aPoints( PolyToPointSequence(
1684 createPolyPolygon_Symbol( rPosition
, rSize
, nStandardSymbol
) ));
1687 xProp
->setPropertyValue( UNO_NAME_POLYPOLYGON
1688 , uno::Any( aPoints
) );
1691 xProp
->setPropertyValue( UNO_NAME_LINECOLOR
1692 , uno::Any( nBorderColor
) );
1695 xProp
->setPropertyValue( UNO_NAME_FILLCOLOR
1696 , uno::Any( nFillColor
) );
1698 catch( const uno::Exception
& )
1700 TOOLS_WARN_EXCEPTION("chart2", "" );
1706 uno::Reference
< drawing::XShape
>
1707 ShapeFactory::createGraphic2D(
1708 const uno::Reference
< drawing::XShapes
>& xTarget
1709 , const drawing::Position3D
& rPosition
1710 , const drawing::Direction3D
& rSize
1711 , const uno::Reference
< graphic::XGraphic
>& xGraphic
)
1713 if( !xTarget
.is() || !xGraphic
.is() )
1716 // @todo: change this to a rectangle shape with a fill bitmap for
1717 // performance reasons (ask AW, said CL)
1720 uno::Reference
< drawing::XShape
> xShape(
1721 m_xShapeFactory
->createInstance(
1722 "com.sun.star.drawing.GraphicObjectShape" ), uno::UNO_QUERY
);
1723 xTarget
->add(xShape
);
1727 // assume position is upper left corner. Transform to center.
1728 drawing::Position3D
aCenterPosition(
1729 rPosition
.PositionX
- (rSize
.DirectionX
/ 2.0),
1730 rPosition
.PositionY
- (rSize
.DirectionY
/ 2.0),
1731 rPosition
.PositionZ
);
1732 xShape
->setPosition( Position3DToAWTPoint( aCenterPosition
));
1733 xShape
->setSize( Direction3DToAWTSize( rSize
));
1735 catch( const uno::Exception
& )
1737 TOOLS_WARN_EXCEPTION("chart2", "" );
1739 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1740 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
1745 xProp
->setPropertyValue( "Graphic", uno::Any( xGraphic
));
1747 catch( const uno::Exception
& )
1749 TOOLS_WARN_EXCEPTION("chart2", "" );
1755 uno::Reference
< drawing::XShapes
>
1756 ShapeFactory::createGroup2D( const uno::Reference
< drawing::XShapes
>& xTarget
1757 , const OUString
& aName
)
1763 //create and add to target
1764 uno::Reference
< drawing::XShape
> xShape(
1765 m_xShapeFactory
->createInstance(
1766 "com.sun.star.drawing.GroupShape" ), uno::UNO_QUERY
);
1767 xTarget
->add(xShape
);
1770 if(!aName
.isEmpty())
1771 setShapeName( xShape
, aName
);
1774 //need this null size as otherwise empty group shapes where painted with a gray border
1775 xShape
->setSize(awt::Size(0,0));
1779 uno::Reference
< drawing::XShapes
> xShapes( xShape
, uno::UNO_QUERY
);
1782 catch( const uno::Exception
& )
1784 TOOLS_WARN_EXCEPTION("chart2", "" );
1789 uno::Reference
< drawing::XShapes
>
1790 ShapeFactory::createGroup3D( const uno::Reference
< drawing::XShapes
>& xTarget
1791 , const OUString
& aName
)
1798 uno::Reference
< drawing::XShape
> xShape(
1799 m_xShapeFactory
->createInstance(
1800 "com.sun.star.drawing.Shape3DSceneObject" ), uno::UNO_QUERY
);
1802 xTarget
->add(xShape
);
1804 //it is necessary to set the transform matrix to initialize the scene properly
1805 //otherwise all objects which are placed into this Group will not be visible
1806 //the following should be unnecessary after the bug is fixed
1809 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1810 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
1815 ::basegfx::B3DHomMatrix aM
;
1816 xProp
->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
1817 , uno::Any(B3DHomMatrixToHomogenMatrix(aM
)) );
1819 catch( const uno::Exception
& )
1821 TOOLS_WARN_EXCEPTION("chart2", "" );
1827 if(!aName
.isEmpty())
1828 setShapeName( xShape
, aName
);
1831 uno::Reference
< drawing::XShapes
> xShapes( xShape
, uno::UNO_QUERY
);
1834 catch( const uno::Exception
& )
1836 TOOLS_WARN_EXCEPTION("chart2", "" );
1841 uno::Reference
< drawing::XShape
>
1842 ShapeFactory::createCircle2D( const uno::Reference
< drawing::XShapes
>& xTarget
1843 , const drawing::Position3D
& rPosition
1844 , const drawing::Direction3D
& rSize
)
1850 uno::Reference
< drawing::XShape
> xShape(
1851 m_xShapeFactory
->createInstance(
1852 "com.sun.star.drawing.EllipseShape" ), uno::UNO_QUERY
);
1853 xTarget
->add(xShape
);
1857 drawing::Position3D
aCenterPosition(
1858 rPosition
.PositionX
- (rSize
.DirectionX
/ 2.0),
1859 rPosition
.PositionY
- (rSize
.DirectionY
/ 2.0),
1860 rPosition
.PositionZ
);
1861 xShape
->setPosition( Position3DToAWTPoint( aCenterPosition
));
1862 xShape
->setSize( Direction3DToAWTSize( rSize
));
1864 catch( const uno::Exception
& )
1866 TOOLS_WARN_EXCEPTION("chart2", "" );
1870 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1871 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
1876 xProp
->setPropertyValue( UNO_NAME_CIRCKIND
, uno::Any( drawing::CircleKind_FULL
) );
1878 catch( const uno::Exception
& )
1880 TOOLS_WARN_EXCEPTION("chart2", "" );
1886 uno::Reference
< drawing::XShape
>
1887 ShapeFactory::createCircle( const uno::Reference
< drawing::XShapes
>& xTarget
1888 , const awt::Size
& rSize
1889 , const awt::Point
& rPosition
)
1891 uno::Reference
< drawing::XShape
> xShape(
1892 m_xShapeFactory
->createInstance(
1893 "com.sun.star.drawing.EllipseShape" ), uno::UNO_QUERY
);
1894 xTarget
->add(xShape
);
1895 xShape
->setSize( rSize
);
1896 xShape
->setPosition( rPosition
);
1901 uno::Reference
< drawing::XShape
>
1902 ShapeFactory::createLine3D( const uno::Reference
< drawing::XShapes
>& xTarget
1903 , const drawing::PolyPolygonShape3D
& rPoints
1904 , const VLineProperties
& rLineProperties
)
1909 if(!rPoints
.SequenceX
.hasElements())
1913 uno::Reference
< drawing::XShape
> xShape(
1914 m_xShapeFactory
->createInstance(
1915 "com.sun.star.drawing.Shape3DPolygonObject" ), uno::UNO_QUERY
);
1916 xTarget
->add(xShape
);
1919 uno::Reference
<beans::XMultiPropertySet
> xMultiPropertySet(xShape
, uno::UNO_QUERY
);
1920 OSL_ENSURE(xMultiPropertySet
.is(), "created shape offers no XMultiPropertySet");
1921 if (xMultiPropertySet
.is())
1925 uno::Sequence
<OUString
> aPropertyNames
{
1926 UNO_NAME_3D_POLYPOLYGON3D
,
1927 UNO_NAME_3D_LINEONLY
1930 uno::Sequence
<uno::Any
> aPropertyValues
{
1931 uno::Any(rPoints
), // Polygon
1932 uno::Any(true) // LineOnly
1936 if(rLineProperties
.Transparence
.hasValue())
1938 lcl_addProperty(aPropertyNames
, aPropertyValues
,
1939 UNO_NAME_LINETRANSPARENCE
,
1940 rLineProperties
.Transparence
);
1944 if(rLineProperties
.LineStyle
.hasValue())
1946 lcl_addProperty(aPropertyNames
, aPropertyValues
,
1948 rLineProperties
.LineStyle
);
1952 if(rLineProperties
.Width
.hasValue())
1954 lcl_addProperty(aPropertyNames
, aPropertyValues
,
1956 rLineProperties
.Width
);
1960 if(rLineProperties
.Color
.hasValue())
1962 lcl_addProperty(aPropertyNames
, aPropertyValues
,
1964 rLineProperties
.Color
);
1966 xMultiPropertySet
->setPropertyValues(aPropertyNames
, aPropertyValues
);
1968 catch( const uno::Exception
& )
1970 TOOLS_WARN_EXCEPTION("chart2", "" );
1976 uno::Reference
< drawing::XShape
>
1977 ShapeFactory::createLine2D( const uno::Reference
< drawing::XShapes
>& xTarget
1978 , const drawing::PointSequenceSequence
& rPoints
1979 , const VLineProperties
* pLineProperties
)
1984 if(!rPoints
.hasElements())
1988 uno::Reference
< drawing::XShape
> xShape(
1989 m_xShapeFactory
->createInstance(
1990 "com.sun.star.drawing.PolyLineShape" ), uno::UNO_QUERY
);
1991 xTarget
->add(xShape
);
1994 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
1995 OSL_ENSURE(xProp
.is(), "created shape offers no XPropertySet");
2001 xProp
->setPropertyValue( UNO_NAME_POLYPOLYGON
2002 , uno::Any( rPoints
) );
2007 if(pLineProperties
->Transparence
.hasValue())
2008 xProp
->setPropertyValue( UNO_NAME_LINETRANSPARENCE
2009 , pLineProperties
->Transparence
);
2012 if(pLineProperties
->LineStyle
.hasValue())
2013 xProp
->setPropertyValue( UNO_NAME_LINESTYLE
2014 , pLineProperties
->LineStyle
);
2017 if(pLineProperties
->Width
.hasValue())
2018 xProp
->setPropertyValue( UNO_NAME_LINEWIDTH
2019 , pLineProperties
->Width
);
2022 if(pLineProperties
->Color
.hasValue())
2023 xProp
->setPropertyValue( UNO_NAME_LINECOLOR
2024 , pLineProperties
->Color
);
2027 if(pLineProperties
->DashName
.hasValue())
2028 xProp
->setPropertyValue( "LineDashName"
2029 , pLineProperties
->DashName
);
2032 catch( const uno::Exception
& )
2034 TOOLS_WARN_EXCEPTION("chart2", "" );
2040 uno::Reference
< drawing::XShape
>
2041 ShapeFactory::createLine ( const uno::Reference
< drawing::XShapes
>& xTarget
,
2042 const awt::Size
& rSize
, const awt::Point
& rPosition
)
2045 uno::Reference
< drawing::XShape
> xShape(
2046 m_xShapeFactory
->createInstance(
2047 "com.sun.star.drawing.LineShape" ), uno::UNO_QUERY
);
2048 xTarget
->add(xShape
);
2049 xShape
->setSize( rSize
);
2050 xShape
->setPosition( rPosition
);
2055 uno::Reference
< drawing::XShape
> ShapeFactory::createInvisibleRectangle(
2056 const uno::Reference
< drawing::XShapes
>& xTarget
2057 , const awt::Size
& rSize
)
2064 uno::Reference
< drawing::XShape
> xShape( m_xShapeFactory
->createInstance(
2065 "com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY
);
2068 xTarget
->add( xShape
);
2069 ShapeFactory::makeShapeInvisible( xShape
);
2070 xShape
->setSize( rSize
);
2074 catch( const uno::Exception
& )
2076 DBG_UNHANDLED_EXCEPTION("chart2");
2081 uno::Reference
< drawing::XShape
> ShapeFactory::createRectangle(
2082 const uno::Reference
< drawing::XShapes
>& xTarget
,
2083 const awt::Size
& rSize
,
2084 const awt::Point
& rPosition
,
2085 const tNameSequence
& rPropNames
,
2086 const tAnySequence
& rPropValues
,
2087 StackPosition ePos
)
2089 uno::Reference
< drawing::XShape
> xShape( m_xShapeFactory
->createInstance(
2090 "com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY
);
2093 if (ePos
== StackPosition::Bottom
)
2095 uno::Reference
<drawing::XShapes2
> xTarget2(xTarget
, uno::UNO_QUERY
);
2097 xTarget2
->addBottom(xShape
);
2100 xTarget
->add(xShape
);
2102 xShape
->setPosition( rPosition
);
2103 xShape
->setSize( rSize
);
2104 uno::Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY_THROW
);
2105 PropertyMapper::setMultiProperties( rPropNames
, rPropValues
, xPropSet
);
2111 uno::Reference
< drawing::XShape
>
2112 ShapeFactory::createRectangle(
2113 const uno::Reference
<
2114 drawing::XShapes
>& xTarget
)
2116 uno::Reference
< drawing::XShape
> xShape( m_xShapeFactory
->createInstance(
2117 "com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY
);
2118 xTarget
->add( xShape
);
2123 uno::Reference
< drawing::XShape
>
2124 ShapeFactory::createText( const uno::Reference
< drawing::XShapes
>& xTarget
2125 , const OUString
& rText
2126 , const tNameSequence
& rPropNames
2127 , const tAnySequence
& rPropValues
2128 , const uno::Any
& rATransformation
)
2136 //create shape and add to page
2137 uno::Reference
< drawing::XShape
> xShape(
2138 m_xShapeFactory
->createInstance(
2139 "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY
);
2140 xTarget
->add(xShape
);
2143 uno::Reference
< text::XTextRange
> xTextRange( xShape
, uno::UNO_QUERY
);
2144 if( xTextRange
.is() )
2145 xTextRange
->setString( rText
);
2147 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
2151 PropertyMapper::setMultiProperties( rPropNames
, rPropValues
, xProp
);
2153 //set position matrix
2154 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2157 if (rATransformation
.hasValue())
2158 xProp
->setPropertyValue( "Transformation", rATransformation
);
2160 SAL_INFO("chart2", "No rATransformation value is given to ShapeFactory::createText()");
2163 catch( const uno::Exception
& )
2165 TOOLS_WARN_EXCEPTION("chart2", "" );
2171 uno::Reference
< drawing::XShape
>
2172 ShapeFactory::createText( const uno::Reference
< drawing::XShapes
>& xTarget
2173 , const uno::Sequence
< OUString
>& rTextParagraphs
2174 , const uno::Sequence
< tNameSequence
>& rParaPropNames
2175 , const uno::Sequence
< tAnySequence
>& rParaPropValues
2176 , const tNameSequence
& rPropNames
2177 , const tAnySequence
& rPropValues
2178 , const uno::Any
& rATransformation
)
2183 if( !rTextParagraphs
.hasElements() )
2186 sal_Int32 nNumberOfParagraphs
= rTextParagraphs
.getLength();
2188 if( rParaPropNames
.getLength() != nNumberOfParagraphs
)
2191 if( rParaPropValues
.getLength() != nNumberOfParagraphs
)
2194 bool bNotEmpty
= false;
2195 for( sal_Int32 nN
= 0; nN
< nNumberOfParagraphs
; ++nN
)
2197 if( !rTextParagraphs
[nN
].isEmpty() )
2206 //create shape and add to page
2207 uno::Reference
< drawing::XShape
> xShape(
2208 m_xShapeFactory
->createInstance(
2209 "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY
);
2210 xTarget
->add(xShape
);
2212 //set paragraph properties
2214 Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
2217 // the first cursor is used for appending the next paragraph,
2218 // after a new string has been inserted the cursor is moved at the end
2219 // of the inserted string
2220 // the second cursor is used for selecting the paragraph and apply the
2221 // passed text properties
2222 Reference
< text::XTextCursor
> xInsertCursor
= xText
->createTextCursor();
2223 Reference
< text::XTextCursor
> xSelectionCursor
= xText
->createTextCursor();
2224 if( xInsertCursor
.is() && xSelectionCursor
.is() )
2226 uno::Reference
< beans::XPropertySet
> xSelectionProp( xSelectionCursor
, uno::UNO_QUERY
);
2227 if( xSelectionProp
.is() )
2229 for( sal_Int32 nN
= 0; nN
< nNumberOfParagraphs
; ++nN
)
2231 if( !rTextParagraphs
[nN
].isEmpty() )
2233 xInsertCursor
->gotoEnd(false);
2236 xText
->insertString( xInsertCursor
, "\n", false );
2238 xSelectionCursor
->gotoEnd(false);
2239 xText
->insertString( xInsertCursor
, rTextParagraphs
[nN
], false );
2241 xSelectionCursor
->gotoEnd(true); // select current paragraph
2242 PropertyMapper::setMultiProperties( rParaPropNames
[nN
], rParaPropValues
[nN
], xSelectionProp
);
2252 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
2255 //set whole text shape properties
2256 PropertyMapper::setMultiProperties( rPropNames
, rPropValues
, xProp
);
2258 if (rATransformation
.hasValue())
2260 //set position matrix
2261 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2264 xProp
->setPropertyValue( "Transformation", rATransformation
);
2266 catch( const uno::Exception
& )
2268 TOOLS_WARN_EXCEPTION("chart2", "" );
2275 uno::Reference
< drawing::XShape
>
2276 ShapeFactory::createText( const uno::Reference
< drawing::XShapes
>& xTarget
2277 , uno::Sequence
< uno::Reference
< chart2::XFormattedString
> >& xFormattedString
2278 , const tNameSequence
& rPropNames
2279 , const tAnySequence
& rPropValues
2280 , const uno::Any
& rATransformation
)
2285 if( !xFormattedString
.hasElements() )
2288 sal_Int32 nNumberOfParagraphs
= xFormattedString
.getLength();
2290 bool bNotEmpty
= false;
2291 for( sal_Int32 nN
= 0; nN
< nNumberOfParagraphs
; ++nN
)
2293 if( !xFormattedString
[nN
]->getString().isEmpty() )
2302 //create shape and add to page
2303 uno::Reference
< drawing::XShape
> xShape(
2304 m_xShapeFactory
->createInstance(
2305 "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY
);
2306 xTarget
->add(xShape
);
2308 //set paragraph properties
2310 Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
2313 // the first cursor is used for appending the next paragraph,
2314 // after a new string has been inserted the cursor is moved at the end
2315 // of the inserted string
2316 // the second cursor is used for selecting the paragraph and apply the
2317 // passed text properties
2318 Reference
< text::XTextCursor
> xInsertCursor
= xText
->createTextCursor();
2319 Reference
< text::XTextCursor
> xSelectionCursor
= xText
->createTextCursor();
2320 if( xInsertCursor
.is() && xSelectionCursor
.is() )
2322 uno::Reference
< beans::XPropertySet
> xSelectionProp( xSelectionCursor
, uno::UNO_QUERY
);
2323 if( xSelectionProp
.is() )
2325 for( sal_Int32 nN
= 0; nN
< nNumberOfParagraphs
; ++nN
)
2327 if( !xFormattedString
[nN
]->getString().isEmpty() )
2329 xInsertCursor
->gotoEnd( false );
2330 xSelectionCursor
->gotoEnd( false );
2331 xText
->insertString( xInsertCursor
, xFormattedString
[nN
]->getString(), false );
2333 xSelectionCursor
->gotoEnd( true ); // select current paragraph
2334 uno::Reference
< beans::XPropertySet
> xStringProperties( xFormattedString
[nN
], uno::UNO_QUERY
);
2335 PropertyMapper::setMappedProperties( xSelectionProp
, xStringProperties
,
2336 PropertyMapper::getPropertyNameMapForTextShapeProperties() );
2346 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
2349 //set whole text shape properties
2350 PropertyMapper::setMultiProperties( rPropNames
, rPropValues
, xProp
);
2352 if( rATransformation
.hasValue() )
2354 //set position matrix
2355 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2358 xProp
->setPropertyValue( "Transformation", rATransformation
);
2360 catch( const uno::Exception
& )
2362 TOOLS_WARN_EXCEPTION("chart2", "" );
2369 uno::Reference
< drawing::XShape
>
2370 ShapeFactory::createText( const uno::Reference
< drawing::XShapes
>& xTarget
,
2371 const awt::Size
& rSize
,
2372 const awt::Point
& rPos
,
2373 uno::Sequence
< uno::Reference
< chart2::XFormattedString
> >& xFormattedString
,
2374 const uno::Reference
<
2375 beans::XPropertySet
> & xTextProperties
,
2376 double nRotation
, const OUString
& aName
)
2378 //create shape and add to page
2379 uno::Reference
< drawing::XShape
> xShape(
2380 m_xShapeFactory
->createInstance(
2381 "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY
);
2384 xTarget
->add(xShape
);
2386 //set text and text properties
2387 uno::Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
2388 uno::Reference
< text::XTextCursor
> xTextCursor( xText
->createTextCursor() );
2389 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
2390 if( !xText
.is() || !xTextCursor
.is() || !xShapeProp
.is() || !xTextProperties
.is() )
2393 tPropertyNameValueMap aValueMap
;
2394 //fill line-, fill- and paragraph-properties into the ValueMap
2396 tPropertyNameMap aNameMap
= PropertyMapper::getPropertyNameMapForParagraphProperties();
2397 auto const & add
= PropertyMapper::getPropertyNameMapForFillAndLineProperties();
2398 aNameMap
.insert(add
.begin(), add
.end());
2400 PropertyMapper::getValueMap( aValueMap
, aNameMap
, xTextProperties
);
2403 //fill some more shape properties into the ValueMap
2405 aValueMap
.insert( { "TextHorizontalAdjust", uno::Any(drawing::TextHorizontalAdjust_CENTER
) } ); // drawing::TextHorizontalAdjust
2406 aValueMap
.insert( { "TextVerticalAdjust", uno::Any(drawing::TextVerticalAdjust_CENTER
) } ); //drawing::TextVerticalAdjust
2407 aValueMap
.insert( { "TextAutoGrowHeight", uno::Any(true) } ); // sal_Bool
2408 aValueMap
.insert( { "TextAutoGrowWidth", uno::Any(true) } ); // sal_Bool
2409 aValueMap
.insert( { "TextMaximumFrameWidth", uno::Any(rSize
.Width
) } ); // sal_Int32
2411 //set name/classified ObjectID (CID)
2412 if( !aName
.isEmpty() )
2413 aValueMap
.emplace( "Name", uno::Any( aName
) ); //CID OUString
2416 //set global title properties
2418 tNameSequence aPropNames
;
2419 tAnySequence aPropValues
;
2420 PropertyMapper::getMultiPropertyListsFromValueMap( aPropNames
, aPropValues
, aValueMap
);
2421 PropertyMapper::setMultiProperties( aPropNames
, aPropValues
, xShapeProp
);
2424 bool bStackCharacters(false);
2427 xTextProperties
->getPropertyValue( "StackCharacters" ) >>= bStackCharacters
;
2429 catch( const uno::Exception
& )
2431 TOOLS_WARN_EXCEPTION("chart2", "" );
2434 if(bStackCharacters
)
2436 //if the characters should be stacked we use only the first character properties for code simplicity
2437 if( xFormattedString
.hasElements() )
2440 for( sal_Int32 nN
=0; nN
<xFormattedString
.getLength();nN
++ )
2441 aLabel
+= xFormattedString
[nN
]->getString();
2442 aLabel
= ShapeFactory::getStackedString( aLabel
, bStackCharacters
);
2444 xTextCursor
->gotoEnd(false);
2445 xText
->insertString( xTextCursor
, aLabel
, false );
2446 xTextCursor
->gotoEnd(true);
2447 uno::Reference
< beans::XPropertySet
> xTargetProps( xShape
, uno::UNO_QUERY
);
2448 uno::Reference
< beans::XPropertySet
> xSourceProps( xFormattedString
[0], uno::UNO_QUERY
);
2450 PropertyMapper::setMappedProperties( xTargetProps
, xSourceProps
2451 , PropertyMapper::getPropertyNameMapForCharacterProperties() );
2453 // adapt font size according to page size
2454 awt::Size aOldRefSize
;
2455 if( xTextProperties
->getPropertyValue( "ReferencePageSize") >>= aOldRefSize
)
2457 RelativeSizeHelper::adaptFontSizes( xTargetProps
, aOldRefSize
, rSize
);
2464 for( nN
=0; nN
<xFormattedString
.getLength();nN
++ )
2466 xTextCursor
->gotoEnd(false);
2467 xText
->insertString( xTextCursor
, xFormattedString
[nN
]->getString(), false );
2468 xTextCursor
->gotoEnd(true);
2470 awt::Size aOldRefSize
;
2471 bool bHasRefPageSize
=
2472 ( xTextProperties
->getPropertyValue( "ReferencePageSize") >>= aOldRefSize
);
2474 if( xFormattedString
.hasElements() )
2476 uno::Reference
< beans::XPropertySet
> xTargetProps( xShape
, uno::UNO_QUERY
);
2477 uno::Reference
< beans::XPropertySet
> xSourceProps( xFormattedString
[0], uno::UNO_QUERY
);
2478 PropertyMapper::setMappedProperties( xTargetProps
, xSourceProps
, PropertyMapper::getPropertyNameMapForCharacterProperties() );
2480 // adapt font size according to page size
2481 if( bHasRefPageSize
)
2483 RelativeSizeHelper::adaptFontSizes( xTargetProps
, aOldRefSize
, rSize
);
2488 // #i109336# Improve auto positioning in chart
2489 float fFontHeight
= 0.0;
2490 if ( xShapeProp
.is() && ( xShapeProp
->getPropertyValue( "CharHeight" ) >>= fFontHeight
) )
2492 fFontHeight
*= ( 2540.0f
/ 72.0f
); // pt -> 1/100 mm
2493 sal_Int32 nXDistance
= static_cast< sal_Int32
>( ::rtl::math::round( fFontHeight
* 0.18f
) );
2494 sal_Int32 nYDistance
= static_cast< sal_Int32
>( ::rtl::math::round( fFontHeight
* 0.30f
) );
2495 xShapeProp
->setPropertyValue( "TextLeftDistance", uno::Any( nXDistance
) );
2496 xShapeProp
->setPropertyValue( "TextRightDistance", uno::Any( nXDistance
) );
2497 xShapeProp
->setPropertyValue( "TextUpperDistance", uno::Any( nYDistance
) );
2498 xShapeProp
->setPropertyValue( "TextLowerDistance", uno::Any( nYDistance
) );
2500 sal_Int32 nXPos
= rPos
.X
;
2501 sal_Int32 nYPos
= rPos
.Y
;
2503 //set position matrix
2504 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2505 ::basegfx::B2DHomMatrix aM
;
2506 aM
.rotate( -basegfx::deg2rad(nRotation
) );//#i78696#->#i80521#
2507 aM
.translate( nXPos
, nYPos
);
2508 xShapeProp
->setPropertyValue( "Transformation", uno::Any( B2DHomMatrixToHomogenMatrix3(aM
) ) );
2510 catch( const uno::Exception
& )
2512 TOOLS_WARN_EXCEPTION("chart2", "" );
2517 ShapeFactory
* ShapeFactory::getOrCreateShapeFactory(const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
2519 static ShapeFactory
* pShapeFactory
= new ShapeFactory(xFactory
);
2520 return pShapeFactory
;
2523 uno::Reference
< drawing::XShapes
> ShapeFactory::getChartRootShape(
2524 const uno::Reference
< drawing::XDrawPage
>& xDrawPage
)
2526 uno::Reference
< drawing::XShapes
> xRet
;
2527 uno::Reference
< drawing::XShapes
> xShapes( xDrawPage
, uno::UNO_QUERY
);
2530 sal_Int32 nCount
= xShapes
->getCount();
2531 uno::Reference
< drawing::XShape
> xShape
;
2532 for( sal_Int32 nN
= nCount
; nN
--; )
2534 if( xShapes
->getByIndex( nN
) >>= xShape
)
2536 if( ShapeFactory::getShapeName( xShape
) == "com.sun.star.chart2.shapes" )
2538 xRet
.set( xShape
, uno::UNO_QUERY
);
2547 void ShapeFactory::makeShapeInvisible( const uno::Reference
< drawing::XShape
>& xShape
)
2549 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
2550 OSL_ENSURE(xShapeProp
.is(), "created shape offers no XPropertySet");
2551 if( xShapeProp
.is())
2555 xShapeProp
->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_NONE
));
2556 xShapeProp
->setPropertyValue( "FillStyle", uno::Any( drawing::FillStyle_NONE
));
2558 catch( const uno::Exception
& )
2560 TOOLS_WARN_EXCEPTION("chart2", "" );
2565 // set a name/CID at a shape (is used for selection handling)
2567 void ShapeFactory::setShapeName( const uno::Reference
< drawing::XShape
>& xShape
2568 , const OUString
& rName
)
2572 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
2573 OSL_ENSURE(xProp
.is(), "shape offers no XPropertySet");
2578 xProp
->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
2579 , uno::Any( rName
) );
2581 catch( const uno::Exception
& )
2583 TOOLS_WARN_EXCEPTION("chart2", "" );
2588 OUString
ShapeFactory::getShapeName( const uno::Reference
< drawing::XShape
>& xShape
)
2592 uno::Reference
< beans::XPropertySet
> xProp( xShape
, uno::UNO_QUERY
);
2593 OSL_ENSURE(xProp
.is(), "shape offers no XPropertySet");
2598 xProp
->getPropertyValue( UNO_NAME_MISC_OBJ_NAME
) >>= aRet
;
2600 catch( const uno::Exception
& )
2602 TOOLS_WARN_EXCEPTION("chart2", "" );
2609 uno::Any
ShapeFactory::makeTransformation( const awt::Point
& rScreenPosition2D
, double fRotationAnglePi
)
2611 ::basegfx::B2DHomMatrix aM
;
2612 //As autogrow is active the rectangle is automatically expanded to that side
2613 //to which the text is not adjusted.
2614 // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
2615 aM
.rotate( fRotationAnglePi
);
2616 aM
.translate( rScreenPosition2D
.X
, rScreenPosition2D
.Y
);
2617 uno::Any
aATransformation( B2DHomMatrixToHomogenMatrix3(aM
) );
2618 return aATransformation
;
2621 OUString
ShapeFactory::getStackedString( const OUString
& rString
, bool bStacked
)
2623 sal_Int32 nLen
= rString
.getLength();
2624 if(!bStacked
|| !nLen
)
2627 OUStringBuffer aStackStr
;
2629 //add a newline after each letter
2630 //as we do not no letters here add a newline after each char
2631 for( sal_Int32 nPosSrc
=0; nPosSrc
< nLen
; nPosSrc
++ )
2634 aStackStr
.append( '\r' );
2635 aStackStr
.append(rString
[nPosSrc
]);
2637 return aStackStr
.makeStringAndClear();
2640 bool ShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D
& rPoly
)
2642 // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
2643 for( sal_Int32 nIdx
= 0, nCount
= rPoly
.SequenceX
.getLength(); nIdx
< nCount
; ++nIdx
)
2644 if( rPoly
.SequenceX
[ nIdx
].getLength() > 1 )
2649 bool ShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D
& rPoly
)
2651 // true, if empty polypolygon or one polygon with one point
2652 return !rPoly
.SequenceX
.hasElements() ||
2653 ((rPoly
.SequenceX
.getLength() == 1) && (rPoly
.SequenceX
[0].getLength() <= 1));
2656 void ShapeFactory::closePolygon( drawing::PolyPolygonShape3D
& rPoly
)
2658 OSL_ENSURE( rPoly
.SequenceX
.getLength() <= 1, "ShapeFactory::closePolygon - single polygon expected" );
2659 //add a last point == first point
2660 if(isPolygonEmptyOrSinglePoint(rPoly
))
2662 drawing::Position3D
aFirst(rPoly
.SequenceX
[0][0],rPoly
.SequenceY
[0][0],rPoly
.SequenceZ
[0][0]);
2663 AddPointToPoly( rPoly
, aFirst
);
2666 awt::Size
ShapeFactory::calculateNewSizeRespectingAspectRatio(
2667 const awt::Size
& rTargetSize
2668 , const awt::Size
& rSourceSizeWithCorrectAspectRatio
)
2672 double fFactorWidth
= double(rTargetSize
.Width
)/double(rSourceSizeWithCorrectAspectRatio
.Width
);
2673 double fFactorHeight
= double(rTargetSize
.Height
)/double(rSourceSizeWithCorrectAspectRatio
.Height
);
2674 double fFactor
= std::min(fFactorWidth
,fFactorHeight
);
2675 aNewSize
.Width
=static_cast<sal_Int32
>(fFactor
*rSourceSizeWithCorrectAspectRatio
.Width
);
2676 aNewSize
.Height
=static_cast<sal_Int32
>(fFactor
*rSourceSizeWithCorrectAspectRatio
.Height
);
2681 awt::Point
ShapeFactory::calculateTopLeftPositionToCenterObject(
2682 const awt::Point
& rTargetAreaPosition
2683 , const awt::Size
& rTargetAreaSize
2684 , const awt::Size
& rObjectSize
)
2686 awt::Point
aNewPosition(rTargetAreaPosition
);
2687 aNewPosition
.X
+= static_cast<sal_Int32
>(double(rTargetAreaSize
.Width
-rObjectSize
.Width
)/2.0);
2688 aNewPosition
.Y
+= static_cast<sal_Int32
>(double(rTargetAreaSize
.Height
-rObjectSize
.Height
)/2.0);
2689 return aNewPosition
;
2692 ::basegfx::B2IRectangle
ShapeFactory::getRectangleOfShape(
2693 const uno::Reference
< drawing::XShape
>& xShape
)
2695 ::basegfx::B2IRectangle aRet
;
2699 awt::Point aPos
= xShape
->getPosition();
2700 awt::Size aSize
= xShape
->getSize();
2701 aRet
= BaseGFXHelper::makeRectangle(aPos
,aSize
);
2707 awt::Size
ShapeFactory::getSizeAfterRotation(
2708 const uno::Reference
< drawing::XShape
>& xShape
, double fRotationAngleDegree
)
2710 awt::Size
aRet(0,0);
2713 const awt::Size
aSize( xShape
->getSize() );
2715 if( fRotationAngleDegree
== 0.0 )
2719 fRotationAngleDegree
= NormAngle360(fRotationAngleDegree
);
2720 if(fRotationAngleDegree
>270.0)
2721 fRotationAngleDegree
=360.0-fRotationAngleDegree
;
2722 else if(fRotationAngleDegree
>180.0)
2723 fRotationAngleDegree
=fRotationAngleDegree
-180.0;
2724 else if(fRotationAngleDegree
>90.0)
2725 fRotationAngleDegree
=180.0-fRotationAngleDegree
;
2727 const double fAnglePi
= basegfx::deg2rad(fRotationAngleDegree
);
2729 aRet
.Height
= static_cast<sal_Int32
>(
2730 aSize
.Width
*rtl::math::sin( fAnglePi
)
2731 + aSize
.Height
*rtl::math::cos( fAnglePi
));
2732 aRet
.Width
= static_cast<sal_Int32
>(
2733 aSize
.Width
*rtl::math::cos( fAnglePi
)
2734 + aSize
.Height
*rtl::math::sin( fAnglePi
));
2740 void ShapeFactory::removeSubShapes( const uno::Reference
< drawing::XShapes
>& xShapes
)
2744 sal_Int32 nSubCount
= xShapes
->getCount();
2745 uno::Reference
< drawing::XShape
> xShape
;
2746 for( sal_Int32 nS
= nSubCount
; nS
--; )
2748 if( xShapes
->getByIndex( nS
) >>= xShape
)
2749 xShapes
->remove( xShape
);
2756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */