LibreOffice Module chart2 (master) 1
ShapeFactory.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <ShapeFactory.hxx>
21#include <BaseGFXHelper.hxx>
22#include <ViewDefines.hxx>
23#include <Stripe.hxx>
24#include <CommonConverters.hxx>
26#include <PropertyMapper.hxx>
27#include <VLineProperties.hxx>
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/chart2/XFormattedString.hpp>
30#include <com/sun/star/drawing/CircleKind.hpp>
31#include <com/sun/star/drawing/DoubleSequence.hpp>
32#include <com/sun/star/drawing/FlagSequence.hpp>
33#include <com/sun/star/drawing/FillStyle.hpp>
34#include <com/sun/star/drawing/LineStyle.hpp>
35#include <com/sun/star/drawing/NormalsKind.hpp>
36#include <com/sun/star/drawing/PointSequence.hpp>
37#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
38#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
39#include <com/sun/star/drawing/TextureProjectionMode.hpp>
40#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
41#include <com/sun/star/drawing/XShapes2.hpp>
42#include <com/sun/star/graphic/XGraphic.hpp>
43#include <com/sun/star/drawing/XShapes.hpp>
44#include <com/sun/star/style/ParagraphAdjust.hpp>
45#include <com/sun/star/uno/Sequence.hxx>
46#include <com/sun/star/uno/Any.hxx>
47
48#include <editeng/unoprnms.hxx>
49#include <rtl/math.hxx>
50
53#include <svx/svdpage.hxx>
54#include <svx/svdopath.hxx>
56#include <tools/helpers.hxx>
58#include <sal/log.hxx>
59
60#include <algorithm>
61#include <cmath>
62#include <cstddef>
63
64using namespace ::com::sun::star;
65using ::com::sun::star::uno::Reference;
66
67namespace chart
68{
69
70namespace
71{
72
73void lcl_addProperty(uno::Sequence<OUString> & rPropertyNames, uno::Sequence<uno::Any> & rPropertyValues,
74 OUString const & rName, uno::Any const & rAny)
75{
76 rPropertyNames.realloc(rPropertyNames.getLength() + 1);
77 rPropertyNames.getArray()[rPropertyNames.getLength() - 1] = rName;
78
79 rPropertyValues.realloc(rPropertyValues.getLength() + 1);
80 rPropertyValues.getArray()[rPropertyValues.getLength() - 1] = rAny;
81}
82
83css::drawing::PolyPolygonShape3D toPolyPolygonShape3D(const std::vector<std::vector<css::drawing::Position3D>>& rPoints)
84{
85 css::drawing::PolyPolygonShape3D aUnoPoly;
86 aUnoPoly.SequenceX.realloc(rPoints.size());
87 aUnoPoly.SequenceY.realloc(rPoints.size());
88 aUnoPoly.SequenceZ.realloc(rPoints.size());
89 for (std::size_t nPolygonIndex=0; nPolygonIndex<rPoints.size(); ++nPolygonIndex)
90 {
91 drawing::DoubleSequence* pOuterSequenceX = &aUnoPoly.SequenceX.getArray()[nPolygonIndex];
92 drawing::DoubleSequence* pOuterSequenceY = &aUnoPoly.SequenceY.getArray()[nPolygonIndex];
93 drawing::DoubleSequence* pOuterSequenceZ = &aUnoPoly.SequenceZ.getArray()[nPolygonIndex];
94 pOuterSequenceX->realloc(rPoints[nPolygonIndex].size());
95 pOuterSequenceY->realloc(rPoints[nPolygonIndex].size());
96 pOuterSequenceZ->realloc(rPoints[nPolygonIndex].size());
97 double* pInnerSequenceX = pOuterSequenceX->getArray();
98 double* pInnerSequenceY = pOuterSequenceY->getArray();
99 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
100 for (std::size_t nPointIndex=0; nPointIndex<rPoints[nPolygonIndex].size(); ++nPointIndex)
101 {
102 auto& rPos = rPoints[nPolygonIndex][nPointIndex];
103 pInnerSequenceX[nPointIndex] = rPos.PositionX;
104 pInnerSequenceY[nPointIndex] = rPos.PositionY;
105 pInnerSequenceZ[nPointIndex] = rPos.PositionZ;
106 }
107 }
108 return aUnoPoly;
109}
110
111} // end anonymous namespace
112
114 const rtl::Reference<SvxDrawPage>& xDrawPage )
115{
117 if (xRet.is())
118 return xRet;
119
120 // Create a new root shape and set it to the bottom of the page. The root
121 // shape is identified by having the name com.sun.star.chart2.shapes.
122 rtl::Reference<SvxShapeGroup> xShapeGroup = new SvxShapeGroup(nullptr, nullptr);
123 xShapeGroup->setShapeKind(SdrObjKind::Group);
124 // cast to resolve ambiguity in converting to XShape
125 xDrawPage->addBottom(static_cast<SvxShape*>(xShapeGroup.get()));
126
127 setShapeName(xShapeGroup, "com.sun.star.chart2.shapes");
128 xShapeGroup->setSize(awt::Size(0,0));
129
130 return xShapeGroup;
131}
132
134
135// diverse tools::PolyPolygon create methods
136
138 const drawing::Direction3D& rSize, double fRoundedEdge, bool bRounded )
139{
140 OSL_PRECOND(fRoundedEdge>=0, "fRoundedEdge needs to be >= 0");
141
142 // always use extra points, so set percent diagonal to 0.4 which is 0% in the UI (old Chart comment)
143 if( fRoundedEdge == 0.0 && bRounded)
144 fRoundedEdge = 0.4 / 200.0;
145 else if(!bRounded)
146 fRoundedEdge = 0.0;
147
148 //fWidthH stands for Half Width
149 const double fWidthH = rSize.DirectionX >=0.0? rSize.DirectionX/2.0 : -rSize.DirectionX/2.0;
150 const double fHeight = rSize.DirectionY;
151
152 const double fHeightSign = fHeight >= 0.0 ? 1.0 : -1.0;
153
154 const double fOffset = (fWidthH * fRoundedEdge) * 1.05; // increase by 5% for safety
155 const bool bRoundEdges = fRoundedEdge && fOffset < fWidthH && 2.0 * fOffset < fHeightSign*fHeight;
156 const sal_Int32 nPointCount = bRoundEdges ? 13 : 5;
157
158 drawing::PolyPolygonShape3D aPP;
159
160 aPP.SequenceX.realloc(1);
161 aPP.SequenceY.realloc(1);
162 aPP.SequenceZ.realloc(1);
163
164 drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
165 drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
166 drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
167
168 pOuterSequenceX->realloc(nPointCount);
169 pOuterSequenceY->realloc(nPointCount);
170 pOuterSequenceZ->realloc(nPointCount);
171
172 double* pInnerSequenceX = pOuterSequenceX->getArray();
173 double* pInnerSequenceY = pOuterSequenceY->getArray();
174 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
175
176 for(sal_Int32 nN = nPointCount; nN--;)
177 *pInnerSequenceZ++ = 0.0;
178
179 if(nPointCount == 5)
180 {
181 *pInnerSequenceY++ = 0.0;
182 *pInnerSequenceY++ = 0.0;
183 *pInnerSequenceY++ = fHeight;
184 *pInnerSequenceY++ = fHeight;
185 *pInnerSequenceY++ = 0.0;
186
187 *pInnerSequenceX++ = -fWidthH;
188 *pInnerSequenceX++ = fWidthH;
189 *pInnerSequenceX++ = fWidthH;
190 *pInnerSequenceX++ = -fWidthH;
191 *pInnerSequenceX++ = -fWidthH;
192 }
193 else
194 {
195 *pInnerSequenceY++ = 0.0;
196 *pInnerSequenceY++ = 0.0;
197 *pInnerSequenceY++ = 0.0;
198 *pInnerSequenceY++ = fHeightSign*fOffset;
199 *pInnerSequenceY++ = fHeight - fHeightSign*fOffset;
200 *pInnerSequenceY++ = fHeight;
201 *pInnerSequenceY++ = fHeight;
202 *pInnerSequenceY++ = fHeight;
203 *pInnerSequenceY++ = fHeight;
204 *pInnerSequenceY++ = fHeight - fHeightSign*fOffset;
205 *pInnerSequenceY++ = fHeightSign*fOffset;
206 *pInnerSequenceY++ = 0.0;
207 *pInnerSequenceY++ = 0.0;
208
209 *pInnerSequenceX++ = -fWidthH + fOffset;
210 *pInnerSequenceX++ = fWidthH - fOffset;
211 *pInnerSequenceX++ = fWidthH;
212 *pInnerSequenceX++ = fWidthH;
213 *pInnerSequenceX++ = fWidthH;
214 *pInnerSequenceX++ = fWidthH;
215 *pInnerSequenceX++ = fWidthH - fOffset;
216 *pInnerSequenceX++ = -fWidthH + fOffset;
217 *pInnerSequenceX++ = -fWidthH;
218 *pInnerSequenceX++ = -fWidthH;
219 *pInnerSequenceX++ = -fWidthH;
220 *pInnerSequenceX++ = -fWidthH;
221 *pInnerSequenceX++ = -fWidthH + fOffset;
222 }
224}
225
227 double fHeight
228 , double fRadius
229 , sal_Int32& nVerticalSegmentCount )
230{
231 //fHeight may be negative
232 OSL_PRECOND(fRadius>0, "The radius of a cylinder needs to be > 0");
233
234 drawing::PolyPolygonShape3D aPP;
235
236 nVerticalSegmentCount=1;
237
238 aPP.SequenceX.realloc(3);
239 aPP.SequenceY.realloc(3);
240 aPP.SequenceZ.realloc(3);
241
242 drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
243 drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
244 drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
245
246 pOuterSequenceX->realloc(2);
247 pOuterSequenceY->realloc(2);
248 pOuterSequenceZ->realloc(2);
249
250 double* pInnerSequenceX = pOuterSequenceX->getArray();
251 double* pInnerSequenceY = pOuterSequenceY->getArray();
252 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
253
254 double fY1 = 0.0;
255 double fY2 = fHeight;
256
257 if( fHeight<0.0 )
258 std::swap(fY1,fY2);
259
260 for(sal_Int32 nN = 2; nN--;)
261 *pInnerSequenceZ++ = 0.0;
262
263 *pInnerSequenceX++ = 0.0;
264 *pInnerSequenceY++ = fY1;
265
266 *pInnerSequenceX++ = fRadius;
267 *pInnerSequenceY++ = fY1;
268
269 pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
270 pOuterSequenceX->realloc(2);
271 pOuterSequenceY->realloc(2);
272 pOuterSequenceZ->realloc(2);
273
274 pInnerSequenceX = pOuterSequenceX->getArray();
275 pInnerSequenceY = pOuterSequenceY->getArray();
276 pInnerSequenceZ = pOuterSequenceZ->getArray();
277
278 for(sal_Int32 nN = 2; nN--;)
279 *pInnerSequenceZ++ = 0.0;
280
281 *pInnerSequenceX++ = fRadius;
282 *pInnerSequenceY++ = fY1;
283
284 *pInnerSequenceX++ = fRadius;
285 *pInnerSequenceY++ = fY2;
286
287 pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
288 pOuterSequenceX->realloc(2);
289 pOuterSequenceY->realloc(2);
290 pOuterSequenceZ->realloc(2);
291
292 pInnerSequenceX = pOuterSequenceX->getArray();
293 pInnerSequenceY = pOuterSequenceY->getArray();
294 pInnerSequenceZ = pOuterSequenceZ->getArray();
295
296 for(sal_Int32 nN = 2; nN--;)
297 *pInnerSequenceZ++ = 0.0;
298
299 *pInnerSequenceX++ = fRadius;
300 *pInnerSequenceY++ = fY2;
301
302 *pInnerSequenceX++ = 0.0;
303 *pInnerSequenceY++ = fY2;
304
306}
307
308static uno::Any createPolyPolygon_Cone( double fHeight, double fRadius, double fTopHeight
309 , sal_Int32& nVerticalSegmentCount )
310{
311 OSL_PRECOND(fRadius>0, "The radius of a cone needs to be > 0");
312
313 //for stacked charts we need cones without top -> fTopHeight != 0 resp. bTopless == true
314 //fTopHeight indicates the high of the cutted top only (not the full height)
315 bool bTopless = !::rtl::math::approxEqual( fHeight, fHeight + fTopHeight );
316
317 double r1= 0.0, r2 = fRadius;
318 if(bTopless)
319 // #i63212# fHeight may be negative, fTopHeight is always positive -> use fabs(fHeight)
320 r1 = fRadius * fTopHeight/(fabs(fHeight)+fTopHeight);
321
322 nVerticalSegmentCount=1;
323 drawing::PolyPolygonShape3D aPP;
324
325 aPP.SequenceX.realloc(2);
326 aPP.SequenceY.realloc(2);
327 aPP.SequenceZ.realloc(2);
328
329 drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
330 drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
331 drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
332
333 pOuterSequenceX->realloc(2);
334 pOuterSequenceY->realloc(2);
335 pOuterSequenceZ->realloc(2);
336
337 double* pInnerSequenceX = pOuterSequenceX->getArray();
338 double* pInnerSequenceY = pOuterSequenceY->getArray();
339 double* pInnerSequenceZ = pOuterSequenceZ->getArray();
340
341 double fX1 = 0.0;
342 double fX2 = r2;
343 double fX3 = r1;
344
345 double fY1 = 0.0;
346 double fY2 = 0.0;
347 double fY3 = fHeight;
348
349 if( fHeight<0.0 )
350 {
351 std::swap(fX1,fX3);
352 std::swap(fY1,fY3);
353 }
354
355 for(sal_Int32 nN = 2; nN--;)
356 *pInnerSequenceZ++ = 0.0;
357
358 *pInnerSequenceY++ = fY1;
359 *pInnerSequenceX++ = fX1;
360
361 *pInnerSequenceY++ = fY2;
362 *pInnerSequenceX++ = fX2;
363
364 pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
365 pOuterSequenceX->realloc(2);
366 pOuterSequenceY->realloc(2);
367 pOuterSequenceZ->realloc(2);
368
369 pInnerSequenceX = pOuterSequenceX->getArray();
370 pInnerSequenceY = pOuterSequenceY->getArray();
371 pInnerSequenceZ = pOuterSequenceZ->getArray();
372
373 for(sal_Int32 nN = 2; nN--;)
374 *pInnerSequenceZ++ = 0.0;
375
376 *pInnerSequenceY++ = fY2;
377 *pInnerSequenceX++ = fX2;
378
379 *pInnerSequenceY++ = fY3;
380 *pInnerSequenceX++ = fX3;
381
383}
384
385// methods for 3D shape creation
386
390 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
391 , sal_Int32 nRotateZAngleHundredthDegree
392 , const uno::Reference< beans::XPropertySet >& xSourceProp
393 , const tPropertyNameMap& rPropertyNameMap
394 , bool bRounded )
395{
396 if( !xTarget.is() )
397 return nullptr;
398 if( bRounded )
399 {
400 try
401 {
402 if( xSourceProp.is() )
403 {
404 drawing::LineStyle aLineStyle;
405 xSourceProp->getPropertyValue( "BorderStyle" ) >>= aLineStyle;
406 if( aLineStyle == drawing::LineStyle_SOLID )
407 bRounded = false;
408 }
409 }
410 catch( const uno::Exception& )
411 {
412 TOOLS_WARN_EXCEPTION("chart2", "" );
413 }
414 }
415 rtl::Reference<Svx3DExtrudeObject> xShape = impl_createCube( xTarget, rPosition, rSize, nRotateZAngleHundredthDegree, bRounded );
416 if( xSourceProp.is())
417 PropertyMapper::setMappedProperties( *xShape, xSourceProp, rPropertyNameMap );
418 return xShape;
419}
420
424 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
425 , sal_Int32 nRotateZAngleHundredthDegree
426 , bool bRounded )
427{
428 if( !xTarget.is() )
429 return nullptr;
430
431 //create shape
433 xShape->setShapeKind(SdrObjKind::E3D_Extrusion);
434 xTarget->addShape(*xShape);
435
436 //set properties
437 try
438 {
439 //depth
440 double fDepth = rSize.DirectionZ;
441 if (fDepth<0)
442 fDepth*=-1.0;
443
444 //PercentDiagonal
445 sal_Int16 nPercentDiagonal = bRounded ? 3 : 0;
446
447 //Matrix for position
448 basegfx::B3DHomMatrix aHomMatrix;
449 if (nRotateZAngleHundredthDegree != 0)
450 aHomMatrix.rotate(0.0, 0.0, -basegfx::deg2rad<100>(nRotateZAngleHundredthDegree));
451 aHomMatrix.translate(rPosition.PositionX, rPosition.PositionY,
452 rPosition.PositionZ - (fDepth / 2.0));
453
454 uno::Sequence<OUString> aPropertyNames {
459 };
460
462 uno::Any(sal_Int32(fDepth)), // Depth
463 uno::Any(nPercentDiagonal), // PercentDiagonal
464 createPolyPolygon_Cube(rSize, double(nPercentDiagonal) / 200.0, bRounded),
466 };
467
468 xShape->setPropertyValues(aPropertyNames, aPropertyValues);
469 }
470 catch( const uno::Exception& )
471 {
472 TOOLS_WARN_EXCEPTION("chart2", "" );
473 }
474 return xShape;
475}
476
480 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
481 , sal_Int32 nRotateZAngleHundredthDegree )
482{
484 xTarget, rPosition, rSize, 0.0, nRotateZAngleHundredthDegree, true );
485}
486
490 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
491 , double fTopHeight, bool bRotateZ
492 , const uno::Reference< beans::XPropertySet >& xSourceProp
493 , const tPropertyNameMap& rPropertyNameMap )
494{
495 if( !xTarget.is() )
496 return nullptr;
497
499
500 bool bDoubleSided = false;
501 short nRotatedTexture = 0;
502
503 const double fWidth = rSize.DirectionX;
504 const double fDepth = rSize.DirectionZ;
505 const double fHeight = rSize.DirectionY;
506
507 drawing::Position3D aBottomP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth/2.0 );
508 if(bRotateZ)
509 aBottomP1.PositionY -= fWidth/2.0;
510 else
511 aBottomP1.PositionX -= fWidth/2.0;
512 drawing::Position3D aBottomP2( aBottomP1 );
513 if(bRotateZ)
514 aBottomP2.PositionY += fWidth;
515 else
516 aBottomP2.PositionX += fWidth;
517 drawing::Position3D aBottomP3( aBottomP2 );
518 drawing::Position3D aBottomP4( aBottomP1 );
519 aBottomP3.PositionZ += fDepth;
520 aBottomP4.PositionZ += fDepth;
521
522 const double fTopFactor = fTopHeight/(fabs(fHeight)+fTopHeight);
523 drawing::Position3D aTopP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth*fTopFactor/2.0 );
524 if(bRotateZ)
525 {
526 aTopP1.PositionY -= fWidth*fTopFactor/2.0;
527 aTopP1.PositionX += fHeight;
528 }
529 else
530 {
531 aTopP1.PositionX -= fWidth*fTopFactor/2.0;
532 aTopP1.PositionY += fHeight;
533 }
534 drawing::Position3D aTopP2( aTopP1 );
535 if(bRotateZ)
536 aTopP2.PositionY += fWidth*fTopFactor;
537 else
538 aTopP2.PositionX += fWidth*fTopFactor;
539 drawing::Position3D aTopP3( aTopP2 );
540 drawing::Position3D aTopP4( aTopP1 );
541 aTopP3.PositionZ += fDepth*fTopFactor;
542 aTopP4.PositionZ += fDepth*fTopFactor;
543
544 Stripe aStripeBottom( aBottomP1, aBottomP4, aBottomP3, aBottomP2 );
545
546 drawing::Position3D aNormalsBottomP1( aBottomP1 );
547 drawing::Position3D aNormalsBottomP2( aBottomP2 );
548 drawing::Position3D aNormalsBottomP3( aBottomP3 );
549 drawing::Position3D aNormalsBottomP4( aBottomP4 );
550 drawing::Position3D aNormalsTopP1( aBottomP1 );
551 drawing::Position3D aNormalsTopP2( aBottomP2 );
552 drawing::Position3D aNormalsTopP3( aBottomP3 );
553 drawing::Position3D aNormalsTopP4( aBottomP4 );
554 if( bRotateZ )
555 {
556 aNormalsTopP1.PositionX += fHeight;
557 aNormalsTopP2.PositionX += fHeight;
558 aNormalsTopP3.PositionX += fHeight;
559 aNormalsTopP4.PositionX += fHeight;
560 }
561 else
562 {
563 aNormalsTopP1.PositionY += fHeight;
564 aNormalsTopP2.PositionY += fHeight;
565 aNormalsTopP3.PositionY += fHeight;
566 aNormalsTopP4.PositionY += fHeight;
567 }
568
569 bool bInvertPolygon = false;
570 bool bInvertNormals = false;
571
572 if(bRotateZ)
573 {
574 //bars
575 if(fHeight>=0.0)
576 {
577 nRotatedTexture = 2;
578 bInvertNormals = true;
579 aStripeBottom = Stripe( aBottomP1, aBottomP4, aBottomP3, aBottomP2 );
580 }
581 else
582 {
583 bInvertPolygon = true;
584 nRotatedTexture = 1;
585 aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 );
586 }
587 }
588 else
589 {
590 //columns
591 if(fHeight>=0.0)
592 {
593 bInvertPolygon = true;
594 nRotatedTexture = 2;
595 aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 );
596 }
597 else
598 {
599 nRotatedTexture = 3;
600 bInvertNormals = true;
601 aStripeBottom = Stripe( aBottomP4, aBottomP3, aBottomP2, aBottomP1 );
602 }
603 }
604 aStripeBottom.InvertNormal(true);
605
606 Stripe aStripe1( aTopP2, aTopP1, aBottomP1, aBottomP2 );
607 Stripe aStripe2( aTopP3, aTopP2, aBottomP2, aBottomP3 );
608 Stripe aStripe3( aTopP4, aTopP3, aBottomP3, aBottomP4 );
609 Stripe aStripe4( aTopP1, aTopP4, aBottomP4, aBottomP1 );
610
611 if( bInvertPolygon )
612 {
613 aStripe1 = Stripe( aBottomP1, aTopP1, aTopP2, aBottomP2 );
614 aStripe2 = Stripe( aBottomP2, aTopP2, aTopP3, aBottomP3 );
615 aStripe3 = Stripe( aBottomP3, aTopP3, aTopP4, aBottomP4 );
616 aStripe4 = Stripe( aBottomP4, aTopP4, aTopP1, aBottomP1 );
617 }
618
619 Stripe aNormalsStripe1( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP2, aNormalsTopP2 );
620 Stripe aNormalsStripe2( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP3, aNormalsTopP3 );
621 Stripe aNormalsStripe3( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP4, aNormalsTopP4 );
622 Stripe aNormalsStripe4( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP1, aNormalsTopP1 );
623
624 if( bInvertNormals )
625 {
626 aNormalsStripe1 = Stripe( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP1, aNormalsTopP1 );
627 aNormalsStripe2 = Stripe( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP2, aNormalsTopP2 );
628 aNormalsStripe3 = Stripe( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP3, aNormalsTopP3 );
629 aNormalsStripe4 = Stripe( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP4, aNormalsTopP4 );
630 }
631
632 aStripe1.SetManualNormal( aNormalsStripe1.getNormal() );
633 aStripe2.SetManualNormal( aNormalsStripe2.getNormal() );
634 aStripe3.SetManualNormal( aNormalsStripe3.getNormal() );
635 aStripe4.SetManualNormal( aNormalsStripe4.getNormal() );
636
637 const bool bFlatNormals = false;
638 ShapeFactory::createStripe( xGroup, aStripe1, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
639 ShapeFactory::createStripe( xGroup, aStripe2, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
640 ShapeFactory::createStripe( xGroup, aStripe3, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
641 ShapeFactory::createStripe( xGroup, aStripe4, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
642 ShapeFactory::createStripe( xGroup, aStripeBottom, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
643
644 return xGroup;
645}
646
650 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
651 , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree )
652{
653 return impl_createConeOrCylinder( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree, false );
654}
655
659 , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
660 , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree
661 , bool bCylinder )
662{
663 if( !xTarget.is() )
664 return nullptr;
665
666 //create shape
668 xShape->setShapeKind(SdrObjKind::E3D_Lathe);
669 xTarget->addShape(*xShape);
670
671 double fWidth = rSize.DirectionX/2.0; //The depth will be corrected within Matrix
672 double fRadius = fWidth;
673 double fHeight = rSize.DirectionY;
674
675 //set properties
676 try
677 {
678 //Polygon
679 sal_Int32 nVerticalSegmentCount = 0;
680 uno::Any aPPolygon = bCylinder
681 ? createPolyPolygon_Cylinder(fHeight, fRadius, nVerticalSegmentCount)
682 : createPolyPolygon_Cone(fHeight, fRadius, fTopHeight, nVerticalSegmentCount);
683
684 //Matrix for position
685 basegfx::B3DHomMatrix aHomMatrix;
686 if (nRotateZAngleHundredthDegree != 0)
687 aHomMatrix.rotate(0.0,0.0,-basegfx::deg2rad<100>(nRotateZAngleHundredthDegree));
688 //stretch the symmetric objects to given depth
689 aHomMatrix.scale(1.0,1.0,rSize.DirectionZ/rSize.DirectionX);
690 aHomMatrix.translate(rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ);
691
692 uno::Sequence<OUString> aPropertyNames{
699 };
700
702 uno::Any(sal_Int16(5)), // PercentDiagonal
703 aPPolygon, // Polygon
704 uno::Any(B3DHomMatrixToHomogenMatrix(aHomMatrix)), // Matrix
705 uno::Any(CHART_3DOBJECT_SEGMENTCOUNT), // Horizontal Segments
706 uno::Any(nVerticalSegmentCount), // Vertical Segments
707 uno::Any(true) // Reduced lines
708 };
709
710 xShape->setPropertyValues(aPropertyNames, aPropertyValues);
711 }
712 catch( const uno::Exception& )
713 {
714 TOOLS_WARN_EXCEPTION("chart2", "" );
715 }
716 return xShape;
717}
718
719static void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords& rReturn, const drawing::PolyPolygonBezierCoords& rAdd, bool bAppendInverse )
720{
721 if(!rAdd.Coordinates.hasElements())
722 return;
723 sal_Int32 nAddCount = rAdd.Coordinates[0].getLength();
724 if(!nAddCount)
725 return;
726
727 sal_Int32 nOldCount = rReturn.Coordinates[0].getLength();
728
729 auto pCoordinates = rReturn.Coordinates.getArray();
730 pCoordinates[0].realloc(nOldCount + nAddCount + 1);
731 auto pCoordinates0 = pCoordinates[0].getArray();
732 auto pFlags = rReturn.Flags.getArray();
733 pFlags[0].realloc(nOldCount+nAddCount+1);
734 auto pFlags0 = pFlags[0].getArray();
735
736 for(sal_Int32 nN=0;nN<nAddCount; nN++ )
737 {
738 sal_Int32 nAdd = bAppendInverse ? (nAddCount-1-nN) : nN;
739 pCoordinates0[nOldCount+nN] = rAdd.Coordinates[0][nAdd];
740 pFlags0[nOldCount+nN] = rAdd.Flags[0][nAdd];
741 }
742
743 //close
744 pCoordinates0[nOldCount+nAddCount] = rReturn.Coordinates[0][0];
745 pFlags0[nOldCount+nAddCount] = rReturn.Flags[0][0];
746}
747
748static drawing::PolyPolygonBezierCoords getCircularArcBezierCoords(
749 double fStartAngleRadian, double fWidthAngleRadian, double fUnitRadius
750 , const ::basegfx::B2DHomMatrix& rTransformationFromUnitCircle
751 , const double fAngleSubdivisionRadian )
752{
753 //at least one polygon is created using two normal and two control points
754 //if the angle is larger it is separated into multiple sub angles
755
756 drawing::PolyPolygonBezierCoords aReturn;
757 sal_Int32 nSegmentCount = static_cast< sal_Int32 >( fWidthAngleRadian/fAngleSubdivisionRadian );
758 if( fWidthAngleRadian > fAngleSubdivisionRadian*nSegmentCount )
759 nSegmentCount++;
760
761 double fFirstSegmentAngle = fAngleSubdivisionRadian;
762 double fLastSegmentAngle = fAngleSubdivisionRadian;
763 if(nSegmentCount==1)
764 {
765 fFirstSegmentAngle = fWidthAngleRadian;
766 fLastSegmentAngle = 0.0;
767 }
768 else
769 {
770 double fFirstAngleOnSubDivision = (static_cast<sal_Int32>(fStartAngleRadian/fAngleSubdivisionRadian)+1)*fAngleSubdivisionRadian;
771 if( !::rtl::math::approxEqual( fStartAngleRadian, fFirstAngleOnSubDivision ) )
772 fFirstSegmentAngle = fFirstAngleOnSubDivision-fStartAngleRadian;
773
774 if(nSegmentCount>1)
775 {
776 fLastSegmentAngle = fWidthAngleRadian-fFirstSegmentAngle-fAngleSubdivisionRadian*(nSegmentCount-2);
777 if( fLastSegmentAngle<0 )
778 nSegmentCount--;
779 if( fLastSegmentAngle>fAngleSubdivisionRadian )
780 {
781 fLastSegmentAngle-=fAngleSubdivisionRadian;
782 nSegmentCount++;
783 }
784 }
785 }
786
787 sal_Int32 nPointCount = 1 + 3*nSegmentCount; //first point of next segment equals last point of former segment
788
789 drawing::PointSequence aPoints(nPointCount);
790 auto pPoints = aPoints.getArray();
791 drawing::FlagSequence aFlags(nPointCount);
792 auto pFlags = aFlags.getArray();
793
796
797 sal_Int32 nPoint=0;
798 double fCurrentRotateAngle = fStartAngleRadian;
799 for(sal_Int32 nSegment=0; nSegment<nSegmentCount; nSegment++)
800 {
801 double fCurrentSegmentAngle = fAngleSubdivisionRadian;
802 if(nSegment==0)//first segment gets only a smaller peace until the next subdivision
803 fCurrentSegmentAngle = fFirstSegmentAngle;
804 else if(nSegment==(nSegmentCount-1)) //the last segment gets the rest angle that does not fit into equal pieces
805 fCurrentSegmentAngle = fLastSegmentAngle;
806
807 //first create untransformed points for a unit circle arc:
808 const double fCos = cos(fCurrentSegmentAngle/2.0);
809 const double fSin = sin(fCurrentSegmentAngle/2.0);
810 P0.setX(fCos);
811 P3.setX(fCos);
812 P0.setY(-fSin);
813 P3.setY(-P0.getY());
814
815 P1.setX((4.0-fCos)/3.0);
816 P2.setX(P1.getX());
817 P1.setY((1.0-fCos)*(fCos-3.0)/(3.0*fSin));
818 P2.setY(-P1.getY());
819 //transform thus startangle equals NULL
821 aStart.rotate(fCurrentSegmentAngle/2.0 + fCurrentRotateAngle );
822 fCurrentRotateAngle+=fCurrentSegmentAngle;
823
824 aStart.scale( fUnitRadius, fUnitRadius );
825
826 //apply given transformation to get final points
827 P0 = rTransformationFromUnitCircle*(aStart*P0);
828 P1 = rTransformationFromUnitCircle*(aStart*P1);
829 P2 = rTransformationFromUnitCircle*(aStart*P2);
830 P3 = rTransformationFromUnitCircle*(aStart*P3);
831
832 pPoints[nPoint].X = static_cast< sal_Int32 >( P0.getX());
833 pPoints[nPoint].Y = static_cast< sal_Int32 >( P0.getY());
834 pFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
835
836 pPoints[nPoint].X = static_cast< sal_Int32 >( P1.getX());
837 pPoints[nPoint].Y = static_cast< sal_Int32 >( P1.getY());
838 pFlags[nPoint++] = drawing::PolygonFlags_CONTROL;
839
840 pPoints[nPoint].X = static_cast< sal_Int32 >( P2.getX());
841 pPoints[nPoint].Y = static_cast< sal_Int32 >( P2.getY());
842 pFlags [nPoint++] = drawing::PolygonFlags_CONTROL;
843
844 if(nSegment==(nSegmentCount-1))
845 {
846 pPoints[nPoint].X = static_cast< sal_Int32 >( P3.getX());
847 pPoints[nPoint].Y = static_cast< sal_Int32 >( P3.getY());
848 pFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
849 }
850 }
851
852 aReturn.Coordinates = { aPoints };
853 aReturn.Flags = { aFlags };
854
855 return aReturn;
856}
857
858static drawing::PolyPolygonBezierCoords getRingBezierCoords(
859 double fUnitCircleInnerRadius
860 , double fUnitCircleOuterRadius
861 , double fStartAngleRadian, double fWidthAngleRadian
862 , const ::basegfx::B2DHomMatrix& aTransformationFromUnitCircle
863 , const double fAngleSubdivisionRadian )
864{
865 drawing::PolyPolygonBezierCoords aReturn;
866
867 drawing::PolyPolygonBezierCoords aOuterArc = getCircularArcBezierCoords(
868 fStartAngleRadian, fWidthAngleRadian, fUnitCircleOuterRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
869 aReturn.Coordinates = { aOuterArc.Coordinates[0] };
870 aReturn.Flags = { aOuterArc.Flags[0] };
871
872 drawing::PolyPolygonBezierCoords aInnerArc = getCircularArcBezierCoords(
873 fStartAngleRadian, fWidthAngleRadian, fUnitCircleInnerRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
874 appendAndCloseBezierCoords( aReturn, aInnerArc, true );
875
876 return aReturn;
877}
878
882 , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
883 , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
884 , const drawing::Direction3D& rOffset
885 , const drawing::HomogenMatrix& rUnitCircleToScene )
886{
887 if( !xTarget.is() )
888 return nullptr;
889
890 // tdf#123504: both 0 and 360 are valid and different values here!
891 while (fUnitCircleWidthAngleDegree > 360)
892 fUnitCircleWidthAngleDegree -= 360.0;
893 while (fUnitCircleWidthAngleDegree < 0)
894 fUnitCircleWidthAngleDegree += 360.0;
895
896 //create shape
898 xShape->setShapeKind(SdrObjKind::PathFill); // aka ClosedBezierShape
899 xTarget->addShape(*xShape); //need to add the shape before setting of properties
900
901 //set properties
902 try
903 {
904 ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
905 aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
906
907 const double fAngleSubdivisionRadian = M_PI/10.0;
908
909 drawing::PolyPolygonBezierCoords aCoords
910 = getRingBezierCoords(fUnitCircleInnerRadius, fUnitCircleOuterRadius,
911 basegfx::deg2rad(fUnitCircleStartAngleDegree),
912 basegfx::deg2rad(fUnitCircleWidthAngleDegree),
913 aTransformationFromUnitCircle, fAngleSubdivisionRadian);
914
915 xShape->SvxShape::setPropertyValue( "PolyPolygonBezier", uno::Any( aCoords ) );
916 }
917 catch( const uno::Exception& )
918 {
919 TOOLS_WARN_EXCEPTION("chart2", "" );
920 }
921
922 return xShape;
923}
924
928 , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
929 , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
930 , const drawing::Direction3D& rOffset
931 , const drawing::HomogenMatrix& rUnitCircleToScene
932 , double fDepth )
933{
934 if( !xTarget.is() )
935 return nullptr;
936
937 // tdf#123504: both 0 and 360 are valid and different values here!
938 while (fUnitCircleWidthAngleDegree > 360)
939 fUnitCircleWidthAngleDegree -= 360.0;
940 while (fUnitCircleWidthAngleDegree < 0)
941 fUnitCircleWidthAngleDegree += 360.0;
942
943 //create shape
945 xShape->setShapeKind(SdrObjKind::E3D_Extrusion);
946 xTarget->addShape(*xShape); //need to add the shape before setting of properties
947
948 //set properties
949 try
950 {
951 ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
952 aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
953
954 const double fAngleSubdivisionRadian = M_PI/32.0;
955
956 drawing::PolyPolygonBezierCoords aCoords
957 = getRingBezierCoords(fUnitCircleInnerRadius, fUnitCircleOuterRadius,
958 basegfx::deg2rad(fUnitCircleStartAngleDegree),
959 basegfx::deg2rad(fUnitCircleWidthAngleDegree),
960 aTransformationFromUnitCircle, fAngleSubdivisionRadian);
961
962 //depth
963 xShape->setPropertyValue( UNO_NAME_3D_EXTRUDE_DEPTH
964 , uno::Any(static_cast<sal_Int32>(fDepth)) );
965
966 //PercentDiagonal
967 xShape->setPropertyValue( UNO_NAME_3D_PERCENT_DIAGONAL
968 , uno::Any( sal_Int16(0) ) );
969
970 //Polygon
971 drawing::PolyPolygonShape3D aPoly( BezierToPoly(aCoords) );
973 xShape->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
974 , uno::Any( aPoly ) );
975
976 //DoubleSided
977 xShape->setPropertyValue( UNO_NAME_3D_DOUBLE_SIDED
978 , uno::Any( true ) );
979
980 //Reduced lines
981 xShape->setPropertyValue( UNO_NAME_3D_REDUCED_LINE_GEOMETRY
982 , uno::Any( true ) );
983
984 //TextureProjectionMode
985 xShape->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
986 , uno::Any( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
987
988 //TextureProjectionMode
989 xShape->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_X
990 , uno::Any( drawing::TextureProjectionMode_PARALLEL ) );
991 xShape->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
992 , uno::Any( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
993 }
994 catch( const uno::Exception& )
995 {
996 TOOLS_WARN_EXCEPTION("chart2", "" );
997 }
998 return xShape;
999}
1000
1003 , const Stripe& rStripe
1004 , const uno::Reference< beans::XPropertySet >& xSourceProp
1005 , const tPropertyNameMap& rPropertyNameMap
1006 , bool bDoubleSided
1007 , short nRotatedTexture
1008 , bool bFlatNormals )
1009{
1010 if( !xTarget.is() )
1011 return nullptr;
1012
1013 //create shape
1015 xShape->setShapeKind(SdrObjKind::E3D_Polygon);
1016 xTarget->addShape(*xShape);
1017
1018 //set properties
1019 try
1020 {
1021 uno::Sequence<OUString> aPropertyNames{
1027 };
1028
1030 rStripe.getPolyPolygonShape3D(), // Polygon
1031 Stripe::getTexturePolygon(nRotatedTexture), // TexturePolygon
1032 rStripe.getNormalsPolygon(), // Normals Polygon
1033 uno::Any(false), // LineOnly
1034 uno::Any(bDoubleSided) // DoubleSided
1035 };
1036
1037 //NormalsKind
1038 if (bFlatNormals)
1039 lcl_addProperty(aPropertyNames, aPropertyValues,
1040 UNO_NAME_3D_NORMALS_KIND, uno::Any(drawing::NormalsKind_FLAT));
1041
1042 xShape->setPropertyValues(aPropertyNames, aPropertyValues);
1043
1044 if (xSourceProp)
1045 {
1046 PropertyMapper::setMappedProperties(*xShape, xSourceProp, rPropertyNameMap);
1047 }
1048 }
1049 catch( const uno::Exception& )
1050 {
1051 TOOLS_WARN_EXCEPTION("chart2", "" );
1052 }
1053 return xShape;
1054}
1055
1058 , const std::vector<std::vector<css::drawing::Position3D>>& rPolyPolygon
1059 , double fDepth )
1060{
1061 if( !xTarget.is() )
1062 return nullptr;
1063
1064 if( rPolyPolygon.empty() )
1065 return nullptr;
1066
1067 //create shape
1069 xShape->setShapeKind(SdrObjKind::E3D_Extrusion);
1070 xTarget->addShape(*xShape);
1071
1072 css::drawing::PolyPolygonShape3D aUnoPolyPolygon = toPolyPolygonShape3D(rPolyPolygon);
1073
1074 //set properties
1075 try
1076 {
1077 uno::Sequence<OUString> aPropertyNames{
1082 };
1083
1085 uno::Any(sal_Int32(fDepth)), // depth
1086 uno::Any(sal_Int16(0)), // PercentDiagonal
1087 uno::Any(aUnoPolyPolygon), // Polygon
1088 uno::Any(true) // DoubleSided
1089 };
1090
1091 //the z component of the polygon is now ignored by the drawing layer,
1092 //so we need to translate the object via transformation matrix
1093
1094 //Matrix for position
1095 if (!rPolyPolygon.empty() && !rPolyPolygon[0].empty())
1096 {
1098 aM.translate(0, 0, rPolyPolygon[0][0].PositionZ);
1099 drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
1100 lcl_addProperty(aPropertyNames, aPropertyValues, UNO_NAME_3D_TRANSFORM_MATRIX, uno::Any(aHM));
1101 }
1102 xShape->setPropertyValues(aPropertyNames, aPropertyValues);
1103 }
1104 catch( const uno::Exception& )
1105 {
1106 TOOLS_WARN_EXCEPTION("chart2", "" );
1107 }
1108 return xShape;
1109}
1110
1113 , const std::vector<std::vector<css::drawing::Position3D>>& rPolyPolygon )
1114{
1115 if( !xTarget.is() )
1116 return nullptr;
1117
1118 //create shape
1119 rtl::Reference<SdrPathObj> pPath = new SdrPathObj(xTarget->GetSdrObject()->getSdrModelFromSdrObject(), SdrObjKind::Polygon);
1120 xTarget->GetSdrObject()->GetSubList()->InsertObject(pPath.get());
1121
1122 //set properties
1123 try
1124 {
1125 // Polygon
1126 basegfx::B2DPolyPolygon aNewPolyPolygon( PolyToB2DPolyPolygon(rPolyPolygon) );
1127 // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm
1128 pPath->ForceMetricToItemPoolMetric(aNewPolyPolygon);
1129 pPath->SetPathPoly(aNewPolyPolygon);
1130 }
1131 catch( const uno::Exception& )
1132 {
1133 TOOLS_WARN_EXCEPTION("chart2", "" );
1134 }
1135 return static_cast<SvxShapePolyPolygon*>(pPath->getUnoShape().get());
1136}
1137
1138static drawing::PointSequenceSequence createPolyPolygon_Symbol( const drawing::Position3D& rPos
1139 , const drawing::Direction3D& rSize
1140 , sal_Int32 nStandardSymbol )
1141{
1142 if(nStandardSymbol<0)
1143 nStandardSymbol*=-1;
1144 nStandardSymbol = nStandardSymbol%ShapeFactory::getSymbolCount();
1145 SymbolEnum eSymbolType=static_cast<SymbolEnum>(nStandardSymbol);
1146
1147 const double& fX = rPos.PositionX;
1148 const double& fY = rPos.PositionY;
1149
1150 const double fWidthH = rSize.DirectionX/2.0; //fWidthH stands for Half Width
1151 const double fHeightH = rSize.DirectionY/2.0; //fHeightH stands for Half Height
1152
1153 const sal_Int32 nQuarterCount = 35; // points inside a quadrant, used in case circle
1154
1155 sal_Int32 nPointCount = 4; //all arrow symbols only need 4 points
1156 switch( eSymbolType )
1157 {
1158 case Symbol_Square:
1159 case Symbol_Diamond:
1160 case Symbol_Bowtie:
1161 case Symbol_Sandglass:
1163 case Symbol_VerticalBar:
1164 nPointCount = 5;
1165 break;
1166 case Symbol_X:
1167 nPointCount = 13;
1168 break;
1169 case Symbol_Plus:
1170 nPointCount = 13;
1171 break;
1172 case Symbol_Star:
1173 nPointCount = 9;
1174 break;
1175 case Symbol_Asterisk:
1176 nPointCount = 19;
1177 break;
1178 case Symbol_Circle:
1179 nPointCount = 5 + 4 * nQuarterCount;
1180 break;
1181 default:
1182 break;
1183 }
1184
1185 drawing::PointSequenceSequence aPP;
1186
1187 aPP.realloc(1);
1188
1189 uno::Sequence<awt::Point>* pOuterSequence = aPP.getArray();
1190
1191 pOuterSequence->realloc(nPointCount);
1192
1193 awt::Point* pInnerSequence = pOuterSequence->getArray();
1194
1195 auto toPoint = [](double x, double y) -> awt::Point
1196 {
1197 return { static_cast<sal_Int32>(x), static_cast<sal_Int32>(y) };
1198 };
1199 switch(eSymbolType)
1200 {
1201 case Symbol_Square:
1202 {
1203 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1204
1205 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1206
1207 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1208
1209 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1210
1211 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1212 break;
1213 }
1214 case Symbol_UpArrow:
1215 {
1216 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1217
1218 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1219
1220 *pInnerSequence++ = toPoint( fX, fY-fHeightH );
1221
1222 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1223 break;
1224 }
1225 case Symbol_DownArrow:
1226 {
1227 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1228
1229 *pInnerSequence++ = toPoint( fX, fY+fHeightH );
1230
1231 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1232
1233 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1234 break;
1235 }
1236 case Symbol_RightArrow:
1237 {
1238 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1239
1240 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1241
1242 *pInnerSequence++ = toPoint( fX+fWidthH, fY );
1243
1244 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1245 break;
1246 }
1247 case Symbol_LeftArrow:
1248 {
1249 *pInnerSequence++ = toPoint( fX-fWidthH, fY );
1250
1251 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1252
1253 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1254
1255 *pInnerSequence++ = toPoint( fX-fWidthH, fY );
1256 break;
1257 }
1258 case Symbol_Bowtie:
1259 {
1260 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1261
1262 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1263
1264 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1265
1266 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1267
1268 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1269 break;
1270 }
1271 case Symbol_Sandglass:
1272 {
1273 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1274
1275 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1276
1277 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1278
1279 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1280
1281 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1282 break;
1283 }
1284 case Symbol_Diamond:
1285 {
1286 *pInnerSequence++ = toPoint( fX-fWidthH, fY );
1287
1288 *pInnerSequence++ = toPoint( fX, fY+fHeightH );
1289
1290 *pInnerSequence++ = toPoint( fX+fWidthH, fY );
1291
1292 *pInnerSequence++ = toPoint( fX, fY-fHeightH );
1293
1294 *pInnerSequence++ = toPoint( fX-fWidthH, fY );
1295 break;
1296 }
1298 {
1299 *pInnerSequence++ = toPoint( fX-fWidthH, fY-0.2*fHeightH );
1300
1301 *pInnerSequence++ = toPoint( fX+fWidthH, fY-0.2*fHeightH );
1302
1303 *pInnerSequence++ = toPoint( fX+fWidthH, fY+0.2*fHeightH );
1304
1305 *pInnerSequence++ = toPoint( fX-fWidthH, fY+0.2*fHeightH );
1306
1307 *pInnerSequence++ = toPoint( fX-fWidthH, fY-0.2*fHeightH );
1308 break;
1309 }
1310 case Symbol_VerticalBar:
1311 {
1312 *pInnerSequence++ = toPoint( fX-0.2*fWidthH, fY-fHeightH );
1313
1314 *pInnerSequence++ = toPoint( fX+0.2*fWidthH, fY-fHeightH );
1315
1316 *pInnerSequence++ = toPoint( fX+0.2*fWidthH, fY+fHeightH );
1317
1318 *pInnerSequence++ = toPoint( fX-0.2*fWidthH, fY+fHeightH );
1319
1320 *pInnerSequence++ = toPoint( fX-0.2*fWidthH, fY-fHeightH );
1321
1322 break;
1323 }
1324 case Symbol_Circle:
1325 {
1326 double fOmega = M_PI_2 / (nQuarterCount + 1.0);
1327 // one point in the middle of each edge to get full size bounding rectangle
1328 *pInnerSequence++ = toPoint( fX + fWidthH, fY );
1329 // 0 to PI/2
1330 for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1331 {
1332 *pInnerSequence++ = toPoint( fX + fWidthH * cos( i * fOmega ), fY - fHeightH * sin( i * fOmega ) );
1333 }
1334 // PI/2 to PI
1335 *pInnerSequence++ = toPoint( fX, fY - fHeightH );
1336 for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1337 {
1338 *pInnerSequence++ = toPoint( fX - fWidthH * sin( i * fOmega), fY - fHeightH * cos( i * fOmega) );
1339 }
1340 // PI to 3/2*PI
1341 *pInnerSequence++ = toPoint( fX - fWidthH, fY );
1342 for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1343 {
1344 *pInnerSequence++ = toPoint( fX - fWidthH * cos( i * fOmega), fY + fHeightH * sin( i * fOmega) );
1345 }
1346 // 3/2*PI to 2*PI
1347 *pInnerSequence++ = toPoint( fX, fY + fHeightH );
1348 for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1349 {
1350 *pInnerSequence++ = toPoint( fX + fWidthH * sin(i * fOmega), fY + fHeightH * cos(i * fOmega) );
1351 }
1352 // close polygon
1353 *pInnerSequence++ = toPoint( fX + fWidthH, fY );
1354 break;
1355 }
1356 case Symbol_Star:
1357 {
1358 *pInnerSequence++ = toPoint( fX, fY-fHeightH );
1359
1360 *pInnerSequence++ = toPoint( fX+0.2*fWidthH, fY-0.2*fHeightH );
1361
1362 *pInnerSequence++ = toPoint( fX+fWidthH, fY );
1363
1364 *pInnerSequence++ = toPoint( fX+0.2*fWidthH, fY+0.2*fHeightH );
1365
1366 *pInnerSequence++ = toPoint( fX, fY+fHeightH );
1367
1368 *pInnerSequence++ = toPoint( fX-0.2*fWidthH, fY+0.2*fHeightH );
1369
1370 *pInnerSequence++ = toPoint( fX-fWidthH, fY );
1371
1372 *pInnerSequence++ = toPoint( fX-0.2*fWidthH, fY-0.2*fHeightH );
1373
1374 *pInnerSequence++ = toPoint( fX, fY-fHeightH );
1375 break;
1376 }
1377 case Symbol_X:
1378 {
1379 const double fScaleX = fWidthH / 128.0;
1380 const double fScaleY = fHeightH / 128.0;
1381 const double fSmall = sqrt(200.0);
1382 const double fLarge = 128.0 - fSmall;
1383
1384 *pInnerSequence++ = toPoint( fX, fY - fScaleY * fSmall );
1385
1386 *pInnerSequence++ = toPoint( fX - fScaleX * fLarge, fY - fHeightH );
1387
1388 *pInnerSequence++ = toPoint( fX - fWidthH, fY - fScaleY * fLarge );
1389
1390 *pInnerSequence++ = toPoint( fX - fScaleX * fSmall, fY );
1391
1392 *pInnerSequence++ = toPoint( fX - fWidthH, fY + fScaleY * fLarge );
1393
1394 *pInnerSequence++ = toPoint( fX - fScaleX * fLarge, fY + fHeightH );
1395
1396 *pInnerSequence++ = toPoint( fX, fY + fScaleY * fSmall );
1397
1398 *pInnerSequence++ = toPoint( fX + fScaleX * fLarge, fY + fHeightH );
1399
1400 *pInnerSequence++ = toPoint( fX + fWidthH, fY + fScaleY * fLarge );
1401
1402 *pInnerSequence++ = toPoint( fX + fScaleX * fSmall, fY );
1403
1404 *pInnerSequence++ = toPoint( fX + fWidthH, fY - fScaleY * fLarge );
1405
1406 *pInnerSequence++ = toPoint( fX + fScaleX * fLarge, fY - fHeightH );
1407
1408 *pInnerSequence++ = toPoint( fX, fY - fScaleY * fSmall );
1409 break;
1410
1411 }
1412 case Symbol_Plus:
1413 {
1414 const double fScaleX = fWidthH / 128.0;
1415 const double fScaleY = fHeightH / 128.0;
1416 const double fHalf = 10.0; //half line width on 256 size square
1417 const double fdX = fScaleX * fHalf;
1418 const double fdY = fScaleY * fHalf;
1419
1420 *pInnerSequence++ = toPoint( fX-fdX, fY-fHeightH );
1421
1422 *pInnerSequence++ = toPoint( fX-fdX, fY-fdY );
1423
1424 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fdY );
1425
1426 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fdY );
1427
1428 *pInnerSequence++ = toPoint( fX-fdX, fY+fdY );
1429
1430 *pInnerSequence++ = toPoint( fX-fdX, fY+fHeightH );
1431
1432 *pInnerSequence++ = toPoint( fX+fdX, fY+fHeightH );
1433
1434 *pInnerSequence++ = toPoint( fX+fdX, fY+fdY );
1435
1436 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fdY );
1437
1438 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fdY );
1439
1440 *pInnerSequence++ = toPoint( fX+fdX, fY-fdY );
1441
1442 *pInnerSequence++ = toPoint( fX+fdY, fY-fHeightH );
1443
1444 *pInnerSequence++ = toPoint( fX-fdX, fY-fHeightH );
1445 break;
1446
1447 }
1448 case Symbol_Asterisk:
1449 {
1450 const double fHalf = 10.0; // half line width on 256 size square
1451 const double fTwoY = fHalf * sqrt(3.0);
1452 const double fFourY = (128.0 - 2.0 * fHalf ) / sqrt(3.0);
1453 const double fThreeX = 128.0 - fHalf;
1454 const double fThreeY = fHalf * sqrt(3.0) + fFourY;
1455 const double fFiveX = 2.0 * fHalf;
1456
1457 const double fScaleX = fWidthH / 128.0;
1458 const double fScaleY = fHeightH / 128.0;
1459
1460 //1
1461 *pInnerSequence++ = toPoint( fX-fScaleX * fHalf, fY-fHeightH );
1462 //2
1463 *pInnerSequence++ = toPoint( fX-fScaleX * fHalf, fY-fScaleY * fTwoY );
1464 //3
1465 *pInnerSequence++ = toPoint( fX-fScaleX * fThreeX, fY-fScaleY * fThreeY );
1466 //4
1467 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fScaleY * fFourY );
1468 //5
1469 *pInnerSequence++ = toPoint( fX-fScaleX * fFiveX, fY );
1470 //6 as 4
1471 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fScaleY * fFourY );
1472 //7 as 3
1473 *pInnerSequence++ = toPoint( fX-fScaleX * fThreeX, fY+fScaleY * fThreeY );
1474 //8 as 2
1475 *pInnerSequence++ = toPoint( fX-fScaleX * fHalf, fY+fScaleY * fTwoY );
1476 //9 as 1
1477 *pInnerSequence++ = toPoint( fX-fScaleX * fHalf, fY+fHeightH );
1478 //10 as 1
1479 *pInnerSequence++ = toPoint( fX+fScaleX * fHalf, fY+fHeightH );
1480 //11 as 2
1481 *pInnerSequence++ = toPoint( fX+fScaleX * fHalf, fY+fScaleY * fTwoY );
1482 //12 as 3
1483 *pInnerSequence++ = toPoint( fX+fScaleX * fThreeX, fY+fScaleY * fThreeY );
1484 //13 as 4
1485 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fScaleY * fFourY );
1486 //14 as 5
1487 *pInnerSequence++ = toPoint( fX+fScaleX * fFiveX, fY );
1488 //15 as 4
1489 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fScaleY * fFourY );
1490 //16 as 3
1491 *pInnerSequence++ = toPoint( fX+fScaleX * fThreeX, fY-fScaleY * fThreeY );
1492 //17 as 2
1493 *pInnerSequence++ = toPoint( fX+fScaleX * fHalf, fY-fScaleY * fTwoY );
1494 // 18 as 1
1495 *pInnerSequence++ = toPoint( fX+fScaleX * fHalf, fY-fHeightH );
1496 // 19 = 1, closing
1497 *pInnerSequence++ = toPoint( fX-fScaleX * fHalf, fY-fHeightH );
1498 break;
1499 }
1500 default: //case Symbol_Square:
1501 {
1502 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1503
1504 *pInnerSequence++ = toPoint( fX-fWidthH, fY+fHeightH );
1505
1506 *pInnerSequence++ = toPoint( fX+fWidthH, fY+fHeightH );
1507
1508 *pInnerSequence++ = toPoint( fX+fWidthH, fY-fHeightH );
1509
1510 *pInnerSequence++ = toPoint( fX-fWidthH, fY-fHeightH );
1511 break;
1512 }
1513 }
1514
1515 return aPP;
1516}
1517
1521 , const drawing::Position3D& rPosition
1522 , const drawing::Direction3D& rSize
1523 , sal_Int32 nStandardSymbol
1524 , sal_Int32 nBorderColor
1525 , sal_Int32 nFillColor )
1526{
1527 if( !xTarget.is() )
1528 return nullptr;
1529
1530 //create shape
1532 xShape->setShapeKind(SdrObjKind::Polygon);
1533 xTarget->addShape(*xShape);
1534
1535 //set properties
1536 try
1537 {
1538 drawing::PointSequenceSequence aPoints =
1539 createPolyPolygon_Symbol( rPosition, rSize, nStandardSymbol );
1540
1541 //Polygon
1542 xShape->SvxShape::setPropertyValue( UNO_NAME_POLYPOLYGON
1543 , uno::Any( aPoints ) );
1544
1545 //LineColor
1546 xShape->SvxShape::setPropertyValue( UNO_NAME_LINECOLOR
1547 , uno::Any( nBorderColor ) );
1548
1549 //FillColor
1550 xShape->SvxShape::setPropertyValue( UNO_NAME_FILLCOLOR
1551 , uno::Any( nFillColor ) );
1552 }
1553 catch( const uno::Exception& )
1554 {
1555 TOOLS_WARN_EXCEPTION("chart2", "" );
1556 }
1557 return xShape;
1558}
1559
1563 , const drawing::Position3D& rPosition
1564 , const drawing::Direction3D& rSize
1565 , const uno::Reference< graphic::XGraphic >& xGraphic )
1566{
1567 if( !xTarget.is() || !xGraphic.is() )
1568 return nullptr;
1569
1570 // @todo: change this to a rectangle shape with a fill bitmap for
1571 // performance reasons (ask AW, said CL)
1572
1573 //create shape
1575 xShape->setShapeKind(SdrObjKind::Graphic);
1576 xTarget->addShape(*xShape);
1577
1578 try
1579 {
1580 // assume position is upper left corner. Transform to center.
1581 drawing::Position3D aCenterPosition(
1582 rPosition.PositionX - (rSize.DirectionX / 2.0),
1583 rPosition.PositionY - (rSize.DirectionY / 2.0),
1584 rPosition.PositionZ );
1585 xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1586 xShape->setSize( Direction3DToAWTSize( rSize ));
1587 }
1588 catch( const uno::Exception & )
1589 {
1590 TOOLS_WARN_EXCEPTION("chart2", "" );
1591 }
1592 try
1593 {
1594 xShape->SvxShape::setPropertyValue( "Graphic", uno::Any( xGraphic ));
1595 }
1596 catch( const uno::Exception& )
1597 {
1598 TOOLS_WARN_EXCEPTION("chart2", "" );
1599 }
1600 return xShape;
1601}
1602
1605 , const OUString& aName )
1606{
1607 if( !xTarget.is() )
1608 return nullptr;
1609 try
1610 {
1611 //create and add to target
1612 rtl::Reference<SvxShapeGroup> xShapeGroup = new SvxShapeGroup(nullptr, nullptr);
1613 xShapeGroup->setShapeKind(SdrObjKind::Group);
1614 // cast to resolve ambiguity in converting to XShape
1615 xTarget->addShape(*xShapeGroup);
1616
1617 //set name
1618 if(!aName.isEmpty())
1619 setShapeName( xShapeGroup, aName );
1620
1621 {//workaround
1622 //need this null size as otherwise empty group shapes where painted with a gray border
1623 xShapeGroup->setSize(awt::Size(0,0));
1624 }
1625
1626 return xShapeGroup;
1627 }
1628 catch( const uno::Exception& )
1629 {
1630 TOOLS_WARN_EXCEPTION("chart2", "" );
1631 }
1632 return nullptr;
1633}
1634
1637 , const OUString& aName )
1638{
1639 if( !xTarget.is() )
1640 return nullptr;
1641 try
1642 {
1643 //create and add to target
1644 rtl::Reference<SvxShapeGroup> xShapeGroup = new SvxShapeGroup(nullptr, nullptr);
1645 xShapeGroup->setShapeKind(SdrObjKind::Group);
1646 // cast to resolve ambiguity in converting to XShape
1647 xTarget->add(static_cast<SvxShape*>(xShapeGroup.get()));
1648
1649 //set name
1650 if(!aName.isEmpty())
1651 setShapeName( xShapeGroup, aName );
1652
1653 {//workaround
1654 //need this null size as otherwise empty group shapes where painted with a gray border
1655 xShapeGroup->setSize(awt::Size(0,0));
1656 }
1657
1658 return xShapeGroup;
1659 }
1660 catch( const uno::Exception& )
1661 {
1662 TOOLS_WARN_EXCEPTION("chart2", "" );
1663 }
1664 return nullptr;
1665}
1666
1669 , const OUString& aName )
1670{
1671 if( !xTarget.is() )
1672 return nullptr;
1673 try
1674 {
1675 //create shape
1676 rtl::Reference<Svx3DSceneObject> xShape = new Svx3DSceneObject(nullptr, nullptr);
1677 xShape->setShapeKind(SdrObjKind::E3D_Scene);
1678 xTarget->addShape(*xShape);
1679
1680 //it is necessary to set the transform matrix to initialize the scene properly
1681 //otherwise all objects which are placed into this Group will not be visible
1682 //the following should be unnecessary after the bug is fixed
1683 //set properties
1684 try
1685 {
1687 xShape->SvxShape::setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
1689 }
1690 catch( const uno::Exception& )
1691 {
1692 TOOLS_WARN_EXCEPTION("chart2", "" );
1693 }
1694
1695 //set name
1696 if(!aName.isEmpty())
1697 setShapeName( xShape , aName );
1698
1699 //return
1700 return xShape;
1701 }
1702 catch( const uno::Exception& )
1703 {
1704 TOOLS_WARN_EXCEPTION("chart2", "" );
1705 }
1706 return nullptr;
1707}
1708
1711 , const drawing::Position3D& rPosition
1712 , const drawing::Direction3D& rSize )
1713{
1714 if( !xTarget.is() )
1715 return nullptr;
1716
1717 //create shape
1718 rtl::Reference<SvxShapeCircle> xShape = new SvxShapeCircle(nullptr);
1719 xShape->setShapeKind(SdrObjKind::CircleOrEllipse);
1720 xTarget->addShape(*xShape);
1721
1722 try
1723 {
1724 drawing::Position3D aCenterPosition(
1725 rPosition.PositionX - (rSize.DirectionX / 2.0),
1726 rPosition.PositionY - (rSize.DirectionY / 2.0),
1727 rPosition.PositionZ );
1728 xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1729 xShape->setSize( Direction3DToAWTSize( rSize ));
1730 }
1731 catch( const uno::Exception & )
1732 {
1733 TOOLS_WARN_EXCEPTION("chart2", "" );
1734 }
1735
1736 //set properties
1737 try
1738 {
1739 xShape->SvxShape::setPropertyValue( UNO_NAME_CIRCKIND, uno::Any( drawing::CircleKind_FULL ) );
1740 }
1741 catch( const uno::Exception& )
1742 {
1743 TOOLS_WARN_EXCEPTION("chart2", "" );
1744 }
1745 return xShape;
1746}
1747
1750 , const awt::Size& rSize
1751 , const awt::Point& rPosition )
1752{
1753 rtl::Reference<SvxShapeCircle> xShape = new SvxShapeCircle(nullptr);
1754 xShape->setShapeKind(SdrObjKind::CircleOrEllipse);
1755 xTarget->addShape(*xShape);
1756 xShape->setSize( rSize );
1757 xShape->setPosition( rPosition );
1758
1759 return xShape;
1760}
1761
1764 , const std::vector<std::vector<css::drawing::Position3D>>& rPoints
1765 , const VLineProperties& rLineProperties )
1766{
1767 if( !xTarget.is() )
1768 return nullptr;
1769
1770 if(rPoints.empty())
1771 return nullptr;
1772
1773 //create shape
1775 xShape->setShapeKind(SdrObjKind::E3D_Polygon);
1776 xTarget->addShape(*xShape);
1777
1778 css::drawing::PolyPolygonShape3D aUnoPoly = toPolyPolygonShape3D(rPoints);
1779
1780 //set properties
1781 try
1782 {
1783 uno::Sequence<OUString> aPropertyNames {
1786 };
1787
1789 uno::Any(aUnoPoly), // Polygon
1790 uno::Any(true) // LineOnly
1791 };
1792
1793 //Transparency
1794 if(rLineProperties.Transparence.hasValue())
1795 {
1796 lcl_addProperty(aPropertyNames, aPropertyValues,
1798 rLineProperties.Transparence);
1799 }
1800
1801 //LineStyle
1802 if(rLineProperties.LineStyle.hasValue())
1803 {
1804 lcl_addProperty(aPropertyNames, aPropertyValues,
1806 rLineProperties.LineStyle);
1807 }
1808
1809 //LineWidth
1810 if(rLineProperties.Width.hasValue())
1811 {
1812 lcl_addProperty(aPropertyNames, aPropertyValues,
1814 rLineProperties.Width);
1815 }
1816
1817 //LineColor
1818 if(rLineProperties.Color.hasValue())
1819 {
1820 lcl_addProperty(aPropertyNames, aPropertyValues,
1822 rLineProperties.Color);
1823 }
1824 xShape->setPropertyValues(aPropertyNames, aPropertyValues);
1825 }
1826 catch( const uno::Exception& )
1827 {
1828 TOOLS_WARN_EXCEPTION("chart2", "" );
1829 }
1830 return xShape;
1831}
1832
1835 , const drawing::PointSequenceSequence& rPoints
1836 , const VLineProperties* pLineProperties )
1837{
1838 if( !xTarget.is() )
1839 return nullptr;
1840
1841 if(!rPoints.hasElements())
1842 return nullptr;
1843
1844 //create shape
1846 xShape->setShapeKind(SdrObjKind::PolyLine);
1847 xTarget->addShape(*xShape);
1848
1849 //set properties
1850 try
1851 {
1852 //Polygon
1853 xShape->SvxShape::setPropertyValue( UNO_NAME_POLYPOLYGON
1854 , uno::Any( rPoints ) );
1855
1856 if(pLineProperties)
1857 {
1858 //Transparency
1859 if(pLineProperties->Transparence.hasValue())
1860 xShape->SvxShape::setPropertyValue( UNO_NAME_LINETRANSPARENCE
1861 , pLineProperties->Transparence );
1862
1863 //LineStyle
1864 if(pLineProperties->LineStyle.hasValue())
1865 xShape->SvxShape::setPropertyValue( UNO_NAME_LINESTYLE
1866 , pLineProperties->LineStyle );
1867
1868 //LineWidth
1869 if(pLineProperties->Width.hasValue())
1870 xShape->SvxShape::setPropertyValue( UNO_NAME_LINEWIDTH
1871 , pLineProperties->Width );
1872
1873 //LineColor
1874 if(pLineProperties->Color.hasValue())
1875 xShape->SvxShape::setPropertyValue( UNO_NAME_LINECOLOR
1876 , pLineProperties->Color );
1877
1878 //LineDashName
1879 if(pLineProperties->DashName.hasValue())
1880 xShape->SvxShape::setPropertyValue( "LineDashName"
1881 , pLineProperties->DashName );
1882
1883 //LineCap
1884 if(pLineProperties->LineCap.hasValue())
1885 xShape->SvxShape::setPropertyValue( UNO_NAME_LINECAP
1886 , pLineProperties->LineCap );
1887 }
1888 }
1889 catch( const uno::Exception& )
1890 {
1891 TOOLS_WARN_EXCEPTION("chart2", "" );
1892 }
1893 return xShape;
1894}
1895
1898 , const std::vector<std::vector<css::drawing::Position3D>>& rPoints
1899 , const VLineProperties* pLineProperties )
1900{
1901 if( !xTarget.is() )
1902 return nullptr;
1903
1904 if(rPoints.empty())
1905 return nullptr;
1906
1907 //create shape
1909 xShape->setShapeKind(SdrObjKind::PolyLine);
1910 xTarget->addShape(*xShape);
1911
1912 drawing::PointSequenceSequence aAnyPoints = PolyToPointSequence(rPoints);
1913
1914 //set properties
1915 try
1916 {
1917 //Polygon
1918 xShape->SvxShape::setPropertyValue( UNO_NAME_POLYPOLYGON
1919 , uno::Any( aAnyPoints ) );
1920
1921 if(pLineProperties)
1922 {
1923 //Transparency
1924 if(pLineProperties->Transparence.hasValue())
1925 xShape->SvxShape::setPropertyValue( UNO_NAME_LINETRANSPARENCE
1926 , pLineProperties->Transparence );
1927
1928 //LineStyle
1929 if(pLineProperties->LineStyle.hasValue())
1930 xShape->SvxShape::setPropertyValue( UNO_NAME_LINESTYLE
1931 , pLineProperties->LineStyle );
1932
1933 //LineWidth
1934 if(pLineProperties->Width.hasValue())
1935 xShape->SvxShape::setPropertyValue( UNO_NAME_LINEWIDTH
1936 , pLineProperties->Width );
1937
1938 //LineColor
1939 if(pLineProperties->Color.hasValue())
1940 xShape->SvxShape::setPropertyValue( UNO_NAME_LINECOLOR
1941 , pLineProperties->Color );
1942
1943 //LineDashName
1944 if(pLineProperties->DashName.hasValue())
1945 xShape->SvxShape::setPropertyValue( "LineDashName"
1946 , pLineProperties->DashName );
1947
1948 //LineCap
1949 if(pLineProperties->LineCap.hasValue())
1950 xShape->SvxShape::setPropertyValue( UNO_NAME_LINECAP
1951 , pLineProperties->LineCap );
1952 }
1953 }
1954 catch( const uno::Exception& )
1955 {
1956 TOOLS_WARN_EXCEPTION("chart2", "" );
1957 }
1958 return xShape;
1959}
1960
1963 const awt::Size& rSize, const awt::Point& rPosition )
1964{
1965 //create shape
1967 xShape->setShapeKind(SdrObjKind::Line);
1968 xTarget->addShape(*xShape);
1969 xShape->setSize( rSize );
1970 xShape->setPosition( rPosition );
1971
1972 return xShape;
1973}
1974
1977 , const awt::Size& rSize )
1978{
1979 try
1980 {
1981 if(!xTarget.is())
1982 return nullptr;
1983
1984 rtl::Reference<SvxShapeRect> xShape = new SvxShapeRect(nullptr);
1985 xShape->setShapeKind(SdrObjKind::Rectangle);
1986 xTarget->addShape( *xShape );
1988 xShape->setSize( rSize );
1989 return xShape;
1990 }
1991 catch( const uno::Exception & )
1992 {
1993 DBG_UNHANDLED_EXCEPTION("chart2");
1994 }
1995 return nullptr;
1996}
1997
1999 const rtl::Reference<SvxShapeGroupAnyD>& xTarget,
2000 const awt::Size& rSize,
2001 const awt::Point& rPosition,
2002 const tNameSequence& rPropNames,
2003 const tAnySequence& rPropValues,
2004 StackPosition ePos )
2005{
2006 rtl::Reference<SvxShapeRect> xShape = new SvxShapeRect(nullptr);
2007 xShape->setShapeKind(SdrObjKind::Rectangle);
2009 {
2010 uno::Reference<drawing::XShapes2> xTarget2(static_cast<cppu::OWeakObject*>(xTarget.get()), uno::UNO_QUERY);
2011 assert(xTarget2);
2012 if (xTarget2.is())
2013 xTarget2->addBottom(xShape);
2014 }
2015 else
2016 xTarget->addShape(*xShape);
2017
2018 xShape->setPosition( rPosition );
2019 xShape->setSize( rSize );
2020 PropertyMapper::setMultiProperties( rPropNames, rPropValues, *xShape );
2021
2022 return xShape;
2023}
2024
2027 const rtl::Reference<SvxShapeGroupAnyD>& xTarget )
2028{
2029 rtl::Reference<SvxShapeRect> xShape = new SvxShapeRect(nullptr);
2030 xShape->setShapeKind(SdrObjKind::Rectangle);
2031 xTarget->addShape( *xShape );
2032
2033 return xShape;
2034}
2035
2038 , const OUString& rText
2039 , const tNameSequence& rPropNames
2040 , const tAnySequence& rPropValues
2041 , const uno::Any& rATransformation )
2042{
2043 if( !xTarget.is() )
2044 return nullptr;
2045
2046 if(rText.isEmpty())
2047 return nullptr;
2048
2049 //create shape and add to page
2050 rtl::Reference<SvxShapeText> xShape = new SvxShapeText(nullptr);
2051 xShape->setShapeKind(SdrObjKind::Text);
2052 xTarget->addShape(*xShape);
2053
2054 //set text
2055 xShape->setString( rText );
2056
2057 //set properties
2058 PropertyMapper::setMultiProperties( rPropNames, rPropValues, *xShape );
2059
2060 //set position matrix
2061 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2062 try
2063 {
2064 if (rATransformation.hasValue())
2065 xShape->SvxShape::setPropertyValue( "Transformation", rATransformation );
2066 else
2067 SAL_INFO("chart2", "No rATransformation value is given to ShapeFactory::createText()");
2068
2069 }
2070 catch( const uno::Exception& )
2071 {
2072 TOOLS_WARN_EXCEPTION("chart2", "" );
2073 }
2074 return xShape;
2075}
2076
2079 , const uno::Sequence< uno::Reference< chart2::XFormattedString > >& xFormattedString
2080 , const tNameSequence& rPropNames
2081 , const tAnySequence& rPropValues
2082 , const uno::Any& rATransformation )
2083{
2084 if( !xTarget.is() )
2085 return nullptr;
2086
2087 if( !xFormattedString.hasElements() )
2088 return nullptr;
2089
2090 sal_Int32 nNumberOfParagraphs = xFormattedString.getLength();
2091
2092 bool bNotEmpty = false;
2093 for( sal_Int32 nN = 0; nN < nNumberOfParagraphs; ++nN )
2094 {
2095 if( !xFormattedString[nN]->getString().isEmpty() )
2096 {
2097 bNotEmpty = true;
2098 break;
2099 }
2100 }
2101 if( !bNotEmpty )
2102 return nullptr;
2103
2104 //create shape and add to page
2105 rtl::Reference<SvxShapeText> xShape = new SvxShapeText(nullptr);
2106 xShape->setShapeKind(SdrObjKind::Text);
2107 xTarget->addShape(*xShape);
2108
2109 //set paragraph properties
2110 bNotEmpty = false;
2111 // the first cursor is used for appending the next paragraph,
2112 // after a new string has been inserted the cursor is moved at the end
2113 // of the inserted string
2114 // the second cursor is used for selecting the paragraph and apply the
2115 // passed text properties
2116 Reference< text::XTextCursor > xInsertCursor = xShape->createTextCursor();
2117 Reference< text::XTextCursor > xSelectionCursor = xShape->createTextCursor();
2118 if( xInsertCursor.is() && xSelectionCursor.is() )
2119 {
2120 uno::Reference< beans::XPropertySet > xSelectionProp( xSelectionCursor, uno::UNO_QUERY );
2121 if( xSelectionProp.is() )
2122 {
2123 for( sal_Int32 nN = 0; nN < nNumberOfParagraphs; ++nN )
2124 {
2125 if( !xFormattedString[nN]->getString().isEmpty() )
2126 {
2127 xInsertCursor->gotoEnd( false );
2128 xSelectionCursor->gotoEnd( false );
2129 xShape->insertString( xInsertCursor, xFormattedString[nN]->getString(), false );
2130 bNotEmpty = true;
2131 xSelectionCursor->gotoEnd( true ); // select current paragraph
2132 uno::Reference< beans::XPropertySet > xStringProperties( xFormattedString[nN], uno::UNO_QUERY );
2133 PropertyMapper::setMappedProperties( xSelectionProp, xStringProperties,
2135 }
2136 }
2137 }
2138 }
2139
2140 if( !bNotEmpty )
2141 return nullptr;
2142
2143 //set whole text shape properties
2144 PropertyMapper::setMultiProperties( rPropNames, rPropValues, *xShape );
2145
2146 if( rATransformation.hasValue() )
2147 {
2148 //set position matrix
2149 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2150 try
2151 {
2152 xShape->SvxShape::setPropertyValue( "Transformation", rATransformation );
2153 }
2154 catch( const uno::Exception& )
2155 {
2156 TOOLS_WARN_EXCEPTION("chart2", "" );
2157 }
2158 }
2159 return xShape;
2160}
2161
2164 const awt::Size& rSize,
2165 const awt::Point& rPos,
2166 uno::Sequence< uno::Reference< chart2::XFormattedString > >& xFormattedString,
2167 const uno::Reference<
2168 beans::XPropertySet > & xTextProperties,
2169 double nRotation, const OUString& aName, sal_Int32 nTextMaxWidth )
2170{
2171 //create shape and add to page
2172 rtl::Reference<SvxShapeText> xShape = new SvxShapeText(nullptr);
2173 xShape->setShapeKind(SdrObjKind::Text);
2174 try
2175 {
2176 xTarget->addShape(*xShape);
2177
2178 //set text and text properties
2179 uno::Reference< text::XTextCursor > xTextCursor( xShape->createTextCursor() );
2180 if( !xTextCursor.is() )
2181 return xShape;
2182
2183 tPropertyNameValueMap aValueMap;
2184 //fill line-, fill- and paragraph-properties into the ValueMap
2185 {
2188 aNameMap.insert(add.begin(), add.end());
2189
2190 PropertyMapper::getValueMap( aValueMap, aNameMap, xTextProperties );
2191 }
2192
2193 //fill some more shape properties into the ValueMap
2194 {
2195 aValueMap.insert( { "TextHorizontalAdjust", uno::Any(drawing::TextHorizontalAdjust_CENTER) } ); // drawing::TextHorizontalAdjust
2196 aValueMap.insert( { "TextVerticalAdjust", uno::Any(drawing::TextVerticalAdjust_CENTER) } ); //drawing::TextVerticalAdjust
2197 aValueMap.insert( { "TextAutoGrowHeight", uno::Any(true) } ); // sal_Bool
2198 aValueMap.insert( { "TextAutoGrowWidth", uno::Any(true) } ); // sal_Bool
2199 aValueMap.insert( { "TextMaximumFrameWidth", uno::Any(nTextMaxWidth) } ); // sal_Int32
2200
2201 //set name/classified ObjectID (CID)
2202 if( !aName.isEmpty() )
2203 aValueMap.emplace( "Name", uno::Any( aName ) ); //CID OUString
2204 }
2205
2206 //set global title properties
2207 {
2209 tAnySequence aPropValues;
2210 PropertyMapper::getMultiPropertyListsFromValueMap( aPropNames, aPropValues, aValueMap );
2211 PropertyMapper::setMultiProperties( aPropNames, aPropValues, *xShape );
2212 }
2213
2214 bool bStackCharacters(false);
2215 try
2216 {
2217 xTextProperties->getPropertyValue( "StackCharacters" ) >>= bStackCharacters;
2218 }
2219 catch( const uno::Exception& )
2220 {
2221 TOOLS_WARN_EXCEPTION("chart2", "" );
2222 }
2223
2224 if(bStackCharacters)
2225 {
2226 //if the characters should be stacked we use only the first character properties for code simplicity
2227 if( xFormattedString.hasElements() )
2228 {
2229 OUString aLabel;
2230 for( const auto & i : std::as_const(xFormattedString) )
2231 aLabel += i->getString();
2232 aLabel = ShapeFactory::getStackedString( aLabel, bStackCharacters );
2233
2234 xTextCursor->gotoEnd(false);
2235 xShape->insertString( xTextCursor, aLabel, false );
2236 xTextCursor->gotoEnd(true);
2237 uno::Reference< beans::XPropertySet > xSourceProps( xFormattedString[0], uno::UNO_QUERY );
2238
2239 PropertyMapper::setMappedProperties( *xShape, xSourceProps
2241
2242 // adapt font size according to page size
2243 awt::Size aOldRefSize;
2244 if( xTextProperties->getPropertyValue( "ReferencePageSize") >>= aOldRefSize )
2245 {
2246 RelativeSizeHelper::adaptFontSizes( *xShape, aOldRefSize, rSize );
2247 }
2248 }
2249 }
2250 else
2251 {
2252 for( const uno::Reference< chart2::XFormattedString >& rxFS : std::as_const(xFormattedString) )
2253 {
2254 xTextCursor->gotoEnd(false);
2255 xShape->insertString( xTextCursor, rxFS->getString(), false );
2256 xTextCursor->gotoEnd(true);
2257 }
2258 awt::Size aOldRefSize;
2259 bool bHasRefPageSize =
2260 ( xTextProperties->getPropertyValue( "ReferencePageSize") >>= aOldRefSize );
2261
2262 if( xFormattedString.hasElements() )
2263 {
2264 uno::Reference< beans::XPropertySet > xSourceProps( xFormattedString[0], uno::UNO_QUERY );
2266
2267 // adapt font size according to page size
2268 if( bHasRefPageSize )
2269 {
2270 RelativeSizeHelper::adaptFontSizes( *xShape, aOldRefSize, rSize );
2271 }
2272 }
2273 }
2274
2275 // #i109336# Improve auto positioning in chart
2276 float fFontHeight = 0.0;
2277 if ( xShape->SvxShape::getPropertyValue( "CharHeight" ) >>= fFontHeight )
2278 {
2279 fFontHeight = convertPointToMm100(fFontHeight);
2280 sal_Int32 nXDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * 0.18f ) );
2281 sal_Int32 nYDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * 0.30f ) );
2282 xShape->SvxShape::setPropertyValue( "TextLeftDistance", uno::Any( nXDistance ) );
2283 xShape->SvxShape::setPropertyValue( "TextRightDistance", uno::Any( nXDistance ) );
2284 xShape->SvxShape::setPropertyValue( "TextUpperDistance", uno::Any( nYDistance ) );
2285 xShape->SvxShape::setPropertyValue( "TextLowerDistance", uno::Any( nYDistance ) );
2286 }
2287 sal_Int32 nXPos = rPos.X;
2288 sal_Int32 nYPos = rPos.Y;
2289
2290 //set position matrix
2291 //the matrix needs to be set at the end behind autogrow and such position influencing properties
2293 aM.rotate( -basegfx::deg2rad(nRotation) );//#i78696#->#i80521#
2294 aM.translate( nXPos, nYPos );
2295 xShape->SvxShape::setPropertyValue( "Transformation", uno::Any( B2DHomMatrixToHomogenMatrix3(aM) ) );
2296
2297 xShape->SvxShape::setPropertyValue( "ParaAdjust", uno::Any( style::ParagraphAdjust_CENTER ) );
2298 }
2299 catch( const uno::Exception& )
2300 {
2301 TOOLS_WARN_EXCEPTION("chart2", "" );
2302 }
2303 return xShape;
2304}
2305
2307 const rtl::Reference<SvxDrawPage>& xDrawPage )
2308{
2310 const uno::Reference< drawing::XShapes > xShapes = xDrawPage;
2311 if( xShapes.is() )
2312 {
2313 sal_Int32 nCount = xShapes->getCount();
2315 for( sal_Int32 nN = nCount; nN--; )
2316 {
2317 if( xShapes->getByIndex( nN ) >>= xShape )
2318 {
2319 if( ShapeFactory::getShapeName( xShape ) == "com.sun.star.chart2.shapes" )
2320 {
2321 xRet = dynamic_cast<SvxShapeGroupAnyD*>(xShape.get());
2322 assert(xRet);
2323 break;
2324 }
2325 }
2326 }
2327 }
2328 return xRet;
2329}
2330
2332{
2333 try
2334 {
2335 xShape->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_NONE ));
2336 xShape->setPropertyValue( "FillStyle", uno::Any( drawing::FillStyle_NONE ));
2337 }
2338 catch( const uno::Exception& )
2339 {
2340 TOOLS_WARN_EXCEPTION("chart2", "" );
2341 }
2342}
2343
2344// set a name/CID at a shape (is used for selection handling)
2345
2347 , const OUString& rName )
2348{
2349 if(!xShape.is())
2350 return;
2351 try
2352 {
2353 xShape->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
2354 , uno::Any( rName ) );
2355 }
2356 catch( const uno::Exception& )
2357 {
2358 TOOLS_WARN_EXCEPTION("chart2", "" );
2359 }
2360}
2361
2363{
2364 OUString aRet;
2365
2366 uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2367 OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
2368 if( xProp.is())
2369 {
2370 try
2371 {
2372 xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
2373 }
2374 catch( const uno::Exception& )
2375 {
2376 TOOLS_WARN_EXCEPTION("chart2", "" );
2377 }
2378 }
2379
2380 return aRet;
2381}
2382
2383uno::Any ShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
2384{
2386 //As autogrow is active the rectangle is automatically expanded to that side
2387 //to which the text is not adjusted.
2388 // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
2389 aM.rotate( fRotationAnglePi );
2390 aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
2391 uno::Any aATransformation( B2DHomMatrixToHomogenMatrix3(aM) );
2392 return aATransformation;
2393}
2394
2395OUString ShapeFactory::getStackedString( const OUString& rString, bool bStacked )
2396{
2397 sal_Int32 nLen = rString.getLength();
2398 if(!bStacked || !nLen)
2399 return rString;
2400
2401 OUStringBuffer aStackStr;
2402
2403 //add a newline after each letter
2404 //as we do not no letters here add a newline after each char
2405 for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
2406 {
2407 if( nPosSrc )
2408 aStackStr.append( '\r' );
2409 aStackStr.append(rString[nPosSrc]);
2410 }
2411 return aStackStr.makeStringAndClear();
2412}
2413
2414bool ShapeFactory::hasPolygonAnyLines( const std::vector<std::vector<css::drawing::Position3D>>& rPoly)
2415{
2416 // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
2417 for( auto const & i : rPoly )
2418 if( i.size() > 1 )
2419 return true;
2420 return false;
2421}
2422
2423bool ShapeFactory::isPolygonEmptyOrSinglePoint( const drawing::PolyPolygonShape3D& rPoly)
2424{
2425 // true, if empty polypolygon or one polygon with one point
2426 return !rPoly.SequenceX.hasElements() ||
2427 ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
2428}
2429
2430bool ShapeFactory::isPolygonEmptyOrSinglePoint( const std::vector<std::vector<css::drawing::Position3D>>& rPoly)
2431{
2432 // true, if empty polypolygon or one polygon with one point
2433 return rPoly.empty() || ((rPoly.size() == 1) && (rPoly[0].size() <= 1));
2434}
2435
2436void ShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
2437{
2438 OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "ShapeFactory::closePolygon - single polygon expected" );
2439 //add a last point == first point
2441 return;
2442 drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
2443 AddPointToPoly( rPoly, aFirst );
2444}
2445
2446void ShapeFactory::closePolygon( std::vector<std::vector<css::drawing::Position3D>>& rPoly)
2447{
2448 OSL_ENSURE( rPoly.size() <= 1, "ShapeFactory::closePolygon - single polygon expected" );
2449 //add a last point == first point
2451 return;
2452 drawing::Position3D aFirst(rPoly[0][0]);
2453 AddPointToPoly( rPoly, aFirst );
2454}
2455
2457 const awt::Size& rTargetSize
2458 , const awt::Size& rSourceSizeWithCorrectAspectRatio )
2459{
2460 awt::Size aNewSize;
2461
2462 double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
2463 double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
2464 double fFactor = std::min(fFactorWidth,fFactorHeight);
2465 aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
2466 aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
2467
2468 return aNewSize;
2469}
2470
2472 const awt::Point& rTargetAreaPosition
2473 , const awt::Size& rTargetAreaSize
2474 , const awt::Size& rObjectSize )
2475{
2476 awt::Point aNewPosition(rTargetAreaPosition);
2477 aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
2478 aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
2479 return aNewPosition;
2480}
2481
2483{
2485
2486 awt::Point aPos = rShape.getPosition();
2487 awt::Size aSize = rShape.getSize();
2488 aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
2489
2490 return aRet;
2491}
2492
2494 SvxShape& rShape, double fRotationAngleDegree )
2495{
2496 awt::Size aRet(0,0);
2497 const awt::Size aSize( rShape.getSize() );
2498
2499 if( fRotationAngleDegree == 0.0 )
2500 aRet = aSize;
2501 else
2502 {
2503 fRotationAngleDegree = NormAngle360(fRotationAngleDegree);
2504 if(fRotationAngleDegree>270.0)
2505 fRotationAngleDegree=360.0-fRotationAngleDegree;
2506 else if(fRotationAngleDegree>180.0)
2507 fRotationAngleDegree=fRotationAngleDegree-180.0;
2508 else if(fRotationAngleDegree>90.0)
2509 fRotationAngleDegree=180.0-fRotationAngleDegree;
2510
2511 const double fAnglePi = basegfx::deg2rad(fRotationAngleDegree);
2512
2513 aRet.Height = static_cast<sal_Int32>(
2514 aSize.Width*std::sin( fAnglePi )
2515 + aSize.Height*std::cos( fAnglePi ));
2516 aRet.Width = static_cast<sal_Int32>(
2517 aSize.Width*std::cos( fAnglePi )
2518 + aSize.Height*std::sin( fAnglePi ));
2519 }
2520 return aRet;
2521}
2522
2524{
2525 if( xShapes.is() )
2526 {
2527 sal_Int32 nSubCount = xShapes->getCount();
2529 for( sal_Int32 nS = nSubCount; nS--; )
2530 {
2531 if( xShapes->getByIndex( nS ) >>= xShape )
2532 xShapes->remove( xShape );
2533 }
2534 }
2535}
2536
2539{
2540 if (!xTarget.is())
2541 return nullptr;
2542
2543 //create table shape
2544 rtl::Reference<SvxTableShape> xShape = new SvxTableShape(nullptr);
2545 xShape->setShapeKind(SdrObjKind::Table);
2546 xTarget->addShape(*xShape);
2547 if (!rName.isEmpty())
2548 setShapeName(xShape, rName);
2549 return xShape;
2550}
2551
2552} //namespace chart
2553
2554/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
PropertyValueVector_t aPropertyValues
constexpr auto convertPointToMm100(N n)
Sequence< double > P1
Sequence< double > P0
Sequence< double > P2
#define CHART_3DOBJECT_SEGMENTCOUNT
Definition: ViewDefines.hxx:25
virtual css::awt::Point SAL_CALL getPosition() override
virtual css::awt::Size SAL_CALL getSize() override
void rotate(double fRadiant)
void translate(double fX, double fY)
void scale(double fX, double fY)
void rotate(double fAngleX, double fAngleY, double fAngleZ)
void translate(double fX, double fY, double fZ)
void scale(double fX, double fY, double fZ)
void setY(TYPE fY)
void setX(TYPE fX)
static const tPropertyNameMap & getPropertyNameMapForFillAndLineProperties()
static const tPropertyNameMap & getPropertyNameMapForTextShapeProperties()
static void setMultiProperties(const tNameSequence &rNames, const tAnySequence &rValues, SvxShape &xTarget)
static const tPropertyNameMap & getPropertyNameMapForCharacterProperties()
static void getMultiPropertyListsFromValueMap(tNameSequence &rNames, tAnySequence &rValues, const tPropertyNameValueMap &rValueMap)
static void getValueMap(tPropertyNameValueMap &rValueMap, const tPropertyNameMap &rNameMap, const css::uno::Reference< css::beans::XPropertySet > &xSourceProp)
Fetch property values from the source object and map it to the destination container.
static const tPropertyNameMap & getPropertyNameMapForParagraphProperties()
static void setMappedProperties(const css::uno::Reference< css::beans::XPropertySet > &xTarget, const css::uno::Reference< css::beans::XPropertySet > &xSource, const tPropertyNameMap &rMap)
static void adaptFontSizes(const css::uno::Reference< css::beans::XPropertySet > &xTargetProperties, const css::awt::Size &rOldReferenceSize, const css::awt::Size &rNewReferenceSize)
static rtl::Reference< SvxShapeCircle > createCircle2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPos, const css::drawing::Direction3D &rSize)
static void setShapeName(const rtl::Reference< SvxShape > &xShape, const OUString &rName)
static rtl::Reference< SvxShapePolyPolygon > createPieSegment2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree, double fUnitCircleInnerRadius, double fUnitCircleOuterRadius, const css::drawing::Direction3D &rOffset, const css::drawing::HomogenMatrix &rUnitCircleToScene)
static OUString getStackedString(const OUString &rString, bool bStacked)
static rtl::Reference< Svx3DPolygonObject > createLine3D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const std::vector< std::vector< css::drawing::Position3D > > &rPoints, const VLineProperties &rLineProperties)
static rtl::Reference< Svx3DExtrudeObject > createArea3D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const std::vector< std::vector< css::drawing::Position3D > > &rPolyPolygon, double fDepth)
static rtl::Reference< SvxTableShape > createTable(rtl::Reference< SvxShapeGroupAnyD > const &xTarget, OUString const &rName=OUString())
static rtl::Reference< SvxShapeGroupAnyD > getOrCreateChartRootShape(const rtl::Reference< SvxDrawPage > &xPage)
static rtl::Reference< Svx3DPolygonObject > createStripe(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const Stripe &rStripe, const css::uno::Reference< css::beans::XPropertySet > &xSourceProp, const tPropertyNameMap &rPropertyNameMap, bool bDoubleSided, short nRotatedTexture=0, bool bFlatNormals=true)
static void setPageSize(const rtl::Reference< SvxShapeGroupAnyD > &xChartShapes, const css::awt::Size &rSize)
static rtl::Reference< Svx3DLatheObject > impl_createConeOrCylinder(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree, bool bCylinder)
static rtl::Reference< SvxShapeRect > createRectangle(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize, const css::awt::Point &rPosition, const tNameSequence &rPropNames, const tAnySequence &rPropValues, StackPosition ePos=StackPosition::Top)
static rtl::Reference< Svx3DExtrudeObject > createPieSegment(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree, double fUnitCircleInnerRadius, double fUnitCircleOuterRadius, const css::drawing::Direction3D &rOffset, const css::drawing::HomogenMatrix &rUnitCircleToScene, double fDepth)
static rtl::Reference< Svx3DSceneObject > createGroup3D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const OUString &aName=OUString())
static rtl::Reference< SvxShapePolyPolygon > createLine(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize, const css::awt::Point &rPosition)
static void makeShapeInvisible(const rtl::Reference< SvxShape > &rShape)
static css::awt::Size getSizeAfterRotation(SvxShape &rShape, double fRotationAngleDegree)
static rtl::Reference< SvxShapeRect > createInvisibleRectangle(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize)
static bool hasPolygonAnyLines(const std::vector< std::vector< css::drawing::Position3D > > &rPoly)
static rtl::Reference< SvxShapePolyPolygon > createArea2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const std::vector< std::vector< css::drawing::Position3D > > &rPolyPolygon)
static OUString getShapeName(const css::uno::Reference< css::drawing::XShape > &xShape)
static rtl::Reference< SvxShapeText > createText(const rtl::Reference< SvxShapeGroupAnyD > &xTarget2D, const OUString &rText, const tNameSequence &rPropNames, const tAnySequence &rPropValues, const css::uno::Any &rATransformation)
static rtl::Reference< Svx3DLatheObject > createCone(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree)
static sal_Int32 getSymbolCount()
static void closePolygon(css::drawing::PolyPolygonShape3D &rPoly)
static bool isPolygonEmptyOrSinglePoint(const css::drawing::PolyPolygonShape3D &rPoly)
static void removeSubShapes(const rtl::Reference< SvxShapeGroupAnyD > &xShapes)
static rtl::Reference< SvxShapePolyPolygon > createLine2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::PointSequenceSequence &rPoints, const VLineProperties *pLineProperties=nullptr)
static css::awt::Point calculateTopLeftPositionToCenterObject(const css::awt::Point &rTargetAreaPosition, const css::awt::Size &rTargetAreaSize, const css::awt::Size &rObjectSize)
static rtl::Reference< Svx3DExtrudeObject > impl_createCube(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, sal_Int32 nRotateZAngleHundredthDegree, bool bRounded)
static rtl::Reference< Svx3DLatheObject > createCylinder(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, sal_Int32 nRotateZAngleHundredthDegree)
static rtl::Reference< SvxGraphicObject > createGraphic2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPos, const css::drawing::Direction3D &rSize, const css::uno::Reference< css::graphic::XGraphic > &xGraphic)
static rtl::Reference< SvxShapeGroup > createGroup2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const OUString &aName=OUString())
static rtl::Reference< Svx3DExtrudeObject > createCube(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, sal_Int32 nRotateZAngleHundredthDegree, const css::uno::Reference< css::beans::XPropertySet > &xSourceProp, const tPropertyNameMap &rPropertyNameMap, bool bRounded=false)
::basegfx::B2IRectangle getRectangleOfShape(SvxShape &rShape)
static css::uno::Any makeTransformation(const css::awt::Point &rScreenPosition2D, double fRotationAnglePi=0.0)
static css::awt::Size calculateNewSizeRespectingAspectRatio(const css::awt::Size &rTargetSize, const css::awt::Size &rSourceSizeWithCorrectAspectRatio)
static rtl::Reference< Svx3DSceneObject > createPyramid(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPosition, const css::drawing::Direction3D &rSize, double fTopHeight, bool bRotateZ, const css::uno::Reference< css::beans::XPropertySet > &xSourceProp, const tPropertyNameMap &rPropertyNameMap)
static rtl::Reference< SvxShapeCircle > createCircle(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize, const css::awt::Point &rPosition)
static rtl::Reference< SvxShapePolyPolygon > createSymbol2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPos, const css::drawing::Direction3D &rSize, sal_Int32 nStandardSymbol, sal_Int32 nBorderColor, sal_Int32 nFillColor)
static rtl::Reference< SvxShapeGroupAnyD > getChartRootShape(const rtl::Reference< SvxDrawPage > &xPage)
A Stripe represents a 2 dimensional foursquare plane in a 3 dimensional room.
Definition: Stripe.hxx:34
static css::uno::Any getTexturePolygon(short nRotatedTexture)
Definition: Stripe.cxx:177
css::uno::Any getNormalsPolygon() const
Definition: Stripe.cxx:146
css::uno::Any getPolyPolygonShape3D() const
Definition: Stripe.cxx:81
void InvertNormal(bool bInvertNormal)
Definition: Stripe.cxx:76
void SetManualNormal(const css::drawing::Direction3D &rNormal)
Definition: Stripe.cxx:70
css::drawing::Direction3D getNormal() const
Definition: Stripe.cxx:120
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
float y
float x
Reference< XInterface > xTarget
T NormAngle360(T angle)
OUString aName
#define SAL_INFO(area, stream)
constexpr double deg2rad(double v)
size
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B2IRectangle makeRectangle(const css::awt::Point &rPosition, const css::awt::Size &rSize)
static drawing::PointSequenceSequence createPolyPolygon_Symbol(const drawing::Position3D &rPos, const drawing::Direction3D &rSize, sal_Int32 nStandardSymbol)
static drawing::PolyPolygonBezierCoords getCircularArcBezierCoords(double fStartAngleRadian, double fWidthAngleRadian, double fUnitRadius, const ::basegfx::B2DHomMatrix &rTransformationFromUnitCircle, const double fAngleSubdivisionRadian)
@ Symbol_Star
@ Symbol_DownArrow
@ Symbol_Bowtie
@ Symbol_VerticalBar
@ Symbol_Asterisk
@ Symbol_HorizontalBar
@ Symbol_Diamond
@ Symbol_LeftArrow
@ Symbol_Sandglass
@ Symbol_Square
@ Symbol_Plus
@ Symbol_Circle
@ Symbol_RightArrow
@ Symbol_UpArrow
OOO_DLLPUBLIC_CHARTTOOLS css::awt::Point Position3DToAWTPoint(const css::drawing::Position3D &rPos)
Position3D --> awt::Point (2D)
static uno::Any createPolyPolygon_Cone(double fHeight, double fRadius, double fTopHeight, sal_Int32 &nVerticalSegmentCount)
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::HomogenMatrix3 B2DHomMatrixToHomogenMatrix3(const ::basegfx::B2DHomMatrix &rM)
B2DHomMatrix <-> HomogenMatrix3.
OOO_DLLPUBLIC_CHARTTOOLS void AddPointToPoly(css::drawing::PolyPolygonShape3D &rPoly, const css::drawing::Position3D &rPos, sal_Int32 nSequenceIndex=0)
PolyPolygonShape3D + drawing::Position3D -> PolyPolygonShape3D.
css::uno::Sequence< OUString > tNameSequence
static uno::Any createPolyPolygon_Cube(const drawing::Direction3D &rSize, double fRoundedEdge, bool bRounded)
OOO_DLLPUBLIC_CHARTTOOLS basegfx::B2DPolyPolygon PolyToB2DPolyPolygon(const std::vector< std::vector< css::drawing::Position3D > > &rPolyPolygon)
PolyPolygonShape3D -> basegfx::B2DPolyPolygon (2D)
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::PolyPolygonShape3D BezierToPoly(const css::drawing::PolyPolygonBezierCoords &rBezier)
PolyPolygonBezierCoords -> PolyPolygonShape3D.
std::unordered_map< OUString, OUString > tPropertyNameMap
static drawing::PolyPolygonBezierCoords getRingBezierCoords(double fUnitCircleInnerRadius, double fUnitCircleOuterRadius, double fStartAngleRadian, double fWidthAngleRadian, const ::basegfx::B2DHomMatrix &aTransformationFromUnitCircle, const double fAngleSubdivisionRadian)
css::uno::Sequence< css::uno::Any > tAnySequence
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::HomogenMatrix B3DHomMatrixToHomogenMatrix(const ::basegfx::B3DHomMatrix &rM)
diverse methods for class conversions; e.g.
static void appendAndCloseBezierCoords(drawing::PolyPolygonBezierCoords &rReturn, const drawing::PolyPolygonBezierCoords &rAdd, bool bAppendInverse)
std::unordered_map< OUString, css::uno::Any > tPropertyNameValueMap
OOO_DLLPUBLIC_CHARTTOOLS css::awt::Size Direction3DToAWTSize(const css::drawing::Direction3D &rDirection)
Direction3D --> awt::Size (2D)
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B2DHomMatrix IgnoreZ(const ::basegfx::B3DHomMatrix &rM)
basegfx::B3DHomMatrix -> B2DHomMatrix
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::PointSequenceSequence PolyToPointSequence(const css::drawing::PolyPolygonShape3D &rPolyPolygon)
PolyPolygonShape3D -> drawing::PointSequenceSequence (2D)
static uno::Any createPolyPolygon_Cylinder(double fHeight, double fRadius, sal_Int32 &nVerticalSegmentCount)
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B3DHomMatrix HomogenMatrixToB3DHomMatrix(const css::drawing::HomogenMatrix &rHM)
HomogenMatrix -> basegfx::B3DHomMatrix.
OUString getString(const Any &_rAny)
int i
const PropertyStruct aPropNames[]
Point toPoint(const QPoint &rPoint)
bool hasValue()
OUString aLabel
constexpr OUStringLiteral UNO_NAME_FILLCOLOR
constexpr OUStringLiteral UNO_NAME_3D_NORMALSPOLYGON3D
constexpr OUStringLiteral UNO_NAME_3D_TEXTURE_PROJ_X
constexpr OUStringLiteral UNO_NAME_3D_PERCENT_DIAGONAL
constexpr OUStringLiteral UNO_NAME_LINESTYLE
constexpr OUStringLiteral UNO_NAME_3D_NORMALS_KIND
constexpr OUStringLiteral UNO_NAME_LINECAP
constexpr OUStringLiteral UNO_NAME_LINETRANSPARENCE
constexpr OUStringLiteral UNO_NAME_LINEWIDTH
constexpr OUStringLiteral UNO_NAME_3D_LINEONLY
constexpr OUStringLiteral UNO_NAME_3D_TRANSFORM_MATRIX
constexpr OUStringLiteral UNO_NAME_3D_DOUBLE_SIDED
constexpr OUStringLiteral UNO_NAME_3D_POLYPOLYGON3D
constexpr OUStringLiteral UNO_NAME_3D_HORZ_SEGS
constexpr OUStringLiteral UNO_NAME_CIRCKIND
constexpr OUStringLiteral UNO_NAME_3D_VERT_SEGS
constexpr OUStringLiteral UNO_NAME_3D_EXTRUDE_DEPTH
constexpr OUStringLiteral UNO_NAME_3D_TEXTURE_PROJ_Y
constexpr OUStringLiteral UNO_NAME_3D_TEXTUREPOLYGON3D
constexpr OUStringLiteral UNO_NAME_3D_REDUCED_LINE_GEOMETRY
constexpr OUStringLiteral UNO_NAME_POLYPOLYGON
constexpr OUStringLiteral UNO_NAME_LINECOLOR
constexpr OUStringLiteral UNO_NAME_MISC_OBJ_NAME