Line data Source code
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 "ViewDefines.hxx"
22 : #include "Stripe.hxx"
23 : #include "CommonConverters.hxx"
24 : #include "macros.hxx"
25 : #include "PropertyMapper.hxx"
26 : #include <comphelper/InlineContainer.hxx>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/drawing/CircleKind.hpp>
29 : #include <com/sun/star/drawing/DoubleSequence.hpp>
30 : #include <com/sun/star/drawing/FlagSequence.hpp>
31 : #include <com/sun/star/drawing/FillStyle.hpp>
32 : #include <com/sun/star/drawing/LineStyle.hpp>
33 : #include <com/sun/star/drawing/NormalsKind.hpp>
34 : #include <com/sun/star/drawing/PointSequence.hpp>
35 : #include <com/sun/star/drawing/PolygonKind.hpp>
36 : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
37 : #include <com/sun/star/drawing/ProjectionMode.hpp>
38 : #include <com/sun/star/drawing/ShadeMode.hpp>
39 : #include <com/sun/star/drawing/TextFitToSizeType.hpp>
40 : #include <com/sun/star/drawing/TextureProjectionMode.hpp>
41 : #include <com/sun/star/text/XText.hpp>
42 : #include <com/sun/star/uno/Any.hxx>
43 :
44 :
45 : #include <editeng/unoprnms.hxx>
46 : #include <rtl/math.hxx>
47 : #include <svx/svdocirc.hxx>
48 : #include <svx/svdopath.hxx>
49 :
50 : #include <basegfx/point/b2dpoint.hxx>
51 : #include <basegfx/matrix/b3dhommatrix.hxx>
52 :
53 : #include <algorithm>
54 :
55 : using namespace ::com::sun::star;
56 : using ::com::sun::star::uno::Reference;
57 :
58 : //.............................................................................
59 : namespace chart
60 : {
61 : //.............................................................................
62 :
63 : //-----------------------------------------------------------------------------
64 : //-----------------------------------------------------------------------------
65 : // set a name/CID at a shape (is used for selection handling)
66 : //-----------------------------------------------------------------------------
67 : //-----------------------------------------------------------------------------
68 :
69 1435 : void ShapeFactory::setShapeName( const uno::Reference< drawing::XShape >& xShape
70 : , const rtl::OUString& rName )
71 : {
72 1435 : if(!xShape.is())
73 1435 : return;
74 1435 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
75 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
76 1435 : if( xProp.is())
77 : {
78 : try
79 : {
80 1435 : xProp->setPropertyValue( C2U( UNO_NAME_MISC_OBJ_NAME )
81 1435 : , uno::makeAny( rName ) );
82 : }
83 0 : catch( const uno::Exception& e )
84 : {
85 : ASSERT_EXCEPTION( e );
86 : }
87 1435 : }
88 : }
89 :
90 : //-----------------------------------------------------------------------------
91 :
92 243 : rtl::OUString ShapeFactory::getShapeName( const uno::Reference< drawing::XShape >& xShape )
93 : {
94 243 : rtl::OUString aRet;
95 :
96 243 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
97 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
98 243 : if( xProp.is())
99 : {
100 : try
101 : {
102 243 : xProp->getPropertyValue( C2U( UNO_NAME_MISC_OBJ_NAME ) ) >>= aRet;
103 : }
104 0 : catch( const uno::Exception& e )
105 : {
106 : ASSERT_EXCEPTION( e );
107 : }
108 : }
109 :
110 243 : return aRet;
111 : }
112 :
113 : //-----------------------------------------------------------------------------
114 :
115 284 : uno::Reference< drawing::XShapes > ShapeFactory::getChartRootShape(
116 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
117 : {
118 284 : uno::Reference< drawing::XShapes > xRet;
119 284 : uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
120 284 : if( xShapes.is() )
121 : {
122 284 : sal_Int32 nCount = xShapes->getCount();
123 284 : uno::Reference< drawing::XShape > xShape;
124 568 : for( sal_Int32 nN = nCount; nN--; )
125 : {
126 243 : if( xShapes->getByIndex( nN ) >>= xShape )
127 : {
128 243 : if( ShapeFactory::getShapeName( xShape ).equals(C2U("com.sun.star.chart2.shapes")) )
129 : {
130 243 : xRet = uno::Reference< drawing::XShapes >( xShape, uno::UNO_QUERY );
131 243 : break;
132 : }
133 : }
134 284 : }
135 : }
136 284 : return xRet;
137 : }
138 :
139 : //-----------------------------------------------------------------------------
140 :
141 202 : uno::Reference< drawing::XShapes > ShapeFactory::getOrCreateChartRootShape(
142 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
143 : {
144 202 : uno::Reference< drawing::XShapes > xRet( ShapeFactory::getChartRootShape( xDrawPage ) );
145 202 : if( !xRet.is() )
146 : {
147 : //create the root shape
148 : xRet = this->createGroup2D(
149 : uno::Reference<drawing::XShapes>( xDrawPage, uno::UNO_QUERY )
150 41 : , C2U("com.sun.star.chart2.shapes") );
151 : }
152 202 : return xRet;
153 : }
154 :
155 : //-----------------------------------------------------------------------------
156 : //-----------------------------------------------------------------------------
157 : // diverse PolyPolygon create methods
158 : //-----------------------------------------------------------------------------
159 : //-----------------------------------------------------------------------------
160 :
161 0 : uno::Any createPolyPolygon_Cube(
162 : const drawing::Direction3D& rSize, double fRoundedEdge, bool bRounded = true )
163 : {
164 : OSL_PRECOND(fRoundedEdge>=0, "fRoundedEdge needs to be >= 0");
165 :
166 : // always use extra points, so set percent diagonal to 0.4 which is 0% in the UI (old Chart comment)
167 0 : if( fRoundedEdge == 0.0 && bRounded)
168 0 : fRoundedEdge = 0.4 / 200.0;
169 0 : else if(!bRounded)
170 0 : fRoundedEdge = 0.0;
171 :
172 : //fWidthH stands for Half Width
173 0 : const double fWidthH = rSize.DirectionX >=0.0? rSize.DirectionX/2.0 : -rSize.DirectionX/2.0;
174 0 : const double fHeight = rSize.DirectionY;
175 :
176 0 : const double fHeightSign = fHeight >= 0.0 ? 1.0 : -1.0;
177 :
178 0 : const double fOffset = (fWidthH * fRoundedEdge) * 1.05; // increase by 5% for safety
179 0 : const bool bRoundEdges = fRoundedEdge && fOffset < fWidthH && 2.0 * fOffset < fHeightSign*fHeight;
180 0 : const sal_Int32 nPointCount = bRoundEdges ? 13 : 5;
181 :
182 : //--------------------------------------
183 0 : drawing::PolyPolygonShape3D aPP;
184 :
185 0 : aPP.SequenceX.realloc(1);
186 0 : aPP.SequenceY.realloc(1);
187 0 : aPP.SequenceZ.realloc(1);
188 :
189 0 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
190 0 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
191 0 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
192 :
193 0 : pOuterSequenceX->realloc(nPointCount);
194 0 : pOuterSequenceY->realloc(nPointCount);
195 0 : pOuterSequenceZ->realloc(nPointCount);
196 :
197 0 : double* pInnerSequenceX = pOuterSequenceX->getArray();
198 0 : double* pInnerSequenceY = pOuterSequenceY->getArray();
199 0 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
200 :
201 0 : for(sal_Int32 nN = nPointCount; nN--;)
202 0 : *pInnerSequenceZ++ = 0.0;
203 :
204 0 : if(nPointCount == 5)
205 : {
206 0 : *pInnerSequenceY++ = 0.0;
207 0 : *pInnerSequenceY++ = 0.0;
208 0 : *pInnerSequenceY++ = fHeight;
209 0 : *pInnerSequenceY++ = fHeight;
210 0 : *pInnerSequenceY++ = 0.0;
211 :
212 0 : *pInnerSequenceX++ = -fWidthH;
213 0 : *pInnerSequenceX++ = fWidthH;
214 0 : *pInnerSequenceX++ = fWidthH;
215 0 : *pInnerSequenceX++ = -fWidthH;
216 0 : *pInnerSequenceX++ = -fWidthH;
217 : }
218 : else
219 : {
220 0 : *pInnerSequenceY++ = 0.0;
221 0 : *pInnerSequenceY++ = 0.0;
222 0 : *pInnerSequenceY++ = 0.0;
223 0 : *pInnerSequenceY++ = fHeightSign*fOffset;
224 0 : *pInnerSequenceY++ = fHeight - fHeightSign*fOffset;
225 0 : *pInnerSequenceY++ = fHeight;
226 0 : *pInnerSequenceY++ = fHeight;
227 0 : *pInnerSequenceY++ = fHeight;
228 0 : *pInnerSequenceY++ = fHeight;
229 0 : *pInnerSequenceY++ = fHeight - fHeightSign*fOffset;
230 0 : *pInnerSequenceY++ = fHeightSign*fOffset;
231 0 : *pInnerSequenceY++ = 0.0;
232 0 : *pInnerSequenceY++ = 0.0;
233 :
234 0 : *pInnerSequenceX++ = -fWidthH + fOffset;
235 0 : *pInnerSequenceX++ = fWidthH - fOffset;
236 0 : *pInnerSequenceX++ = fWidthH;
237 0 : *pInnerSequenceX++ = fWidthH;
238 0 : *pInnerSequenceX++ = fWidthH;
239 0 : *pInnerSequenceX++ = fWidthH;
240 0 : *pInnerSequenceX++ = fWidthH - fOffset;
241 0 : *pInnerSequenceX++ = -fWidthH + fOffset;
242 0 : *pInnerSequenceX++ = -fWidthH;
243 0 : *pInnerSequenceX++ = -fWidthH;
244 0 : *pInnerSequenceX++ = -fWidthH;
245 0 : *pInnerSequenceX++ = -fWidthH;
246 0 : *pInnerSequenceX++ = -fWidthH + fOffset;
247 : }
248 0 : return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) );
249 : }
250 :
251 0 : uno::Any createPolyPolygon_Cylinder(
252 : double fHeight
253 : , double fRadius
254 : , sal_Int32& nVerticalSegmentCount )
255 : {
256 : //fHeight may be negative
257 : OSL_PRECOND(fRadius>0, "The radius of a cylinder needs to be > 0");
258 :
259 : //--------------------------------------
260 0 : drawing::PolyPolygonShape3D aPP;
261 :
262 0 : nVerticalSegmentCount=1;
263 :
264 0 : aPP.SequenceX.realloc(3);
265 0 : aPP.SequenceY.realloc(3);
266 0 : aPP.SequenceZ.realloc(3);
267 :
268 0 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
269 0 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
270 0 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
271 :
272 0 : pOuterSequenceX->realloc(2);
273 0 : pOuterSequenceY->realloc(2);
274 0 : pOuterSequenceZ->realloc(2);
275 :
276 0 : double* pInnerSequenceX = pOuterSequenceX->getArray();
277 0 : double* pInnerSequenceY = pOuterSequenceY->getArray();
278 0 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
279 :
280 0 : double fY1 = 0.0;
281 0 : double fY2 = fHeight;
282 :
283 0 : if( fHeight<0.0 )
284 0 : ::std::swap(fY1,fY2);
285 :
286 : //----------------------------
287 0 : for(sal_Int32 nN = 2; nN--;)
288 0 : *pInnerSequenceZ++ = 0.0;
289 :
290 0 : *pInnerSequenceX++ = 0.0;
291 0 : *pInnerSequenceY++ = fY1;
292 :
293 0 : *pInnerSequenceX++ = fRadius;
294 0 : *pInnerSequenceY++ = fY1;
295 : //----------------------------
296 :
297 0 : pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
298 0 : pOuterSequenceX->realloc(2);
299 0 : pOuterSequenceY->realloc(2);
300 0 : pOuterSequenceZ->realloc(2);
301 :
302 0 : pInnerSequenceX = pOuterSequenceX->getArray();
303 0 : pInnerSequenceY = pOuterSequenceY->getArray();
304 0 : pInnerSequenceZ = pOuterSequenceZ->getArray();
305 :
306 : //----------------------------
307 0 : for(sal_Int32 nN = 2; nN--;)
308 0 : *pInnerSequenceZ++ = 0.0;
309 :
310 0 : *pInnerSequenceX++ = fRadius;
311 0 : *pInnerSequenceY++ = fY1;
312 :
313 0 : *pInnerSequenceX++ = fRadius;
314 0 : *pInnerSequenceY++ = fY2;
315 : //----------------------------
316 :
317 0 : pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
318 0 : pOuterSequenceX->realloc(2);
319 0 : pOuterSequenceY->realloc(2);
320 0 : pOuterSequenceZ->realloc(2);
321 :
322 0 : pInnerSequenceX = pOuterSequenceX->getArray();
323 0 : pInnerSequenceY = pOuterSequenceY->getArray();
324 0 : pInnerSequenceZ = pOuterSequenceZ->getArray();
325 :
326 : //----------------------------
327 0 : for(sal_Int32 nN = 2; nN--;)
328 0 : *pInnerSequenceZ++ = 0.0;
329 :
330 0 : *pInnerSequenceX++ = fRadius;
331 0 : *pInnerSequenceY++ = fY2;
332 :
333 0 : *pInnerSequenceX++ = 0.0;
334 0 : *pInnerSequenceY++ = fY2;
335 : //----------------------------
336 :
337 0 : return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) );
338 : }
339 :
340 0 : uno::Any createPolyPolygon_Cone( double fHeight, double fRadius, double fTopHeight
341 : , sal_Int32& nVerticalSegmentCount )
342 : {
343 : OSL_PRECOND(fRadius>0, "The radius of a cone needs to be > 0");
344 :
345 : //for stacked charts we need cones without top -> fTopHeight != 0 resp. bTopless == true
346 : //fTopHeight indicates the high of the cutted top only (not the full height)
347 0 : bool bTopless = !::rtl::math::approxEqual( fHeight, fHeight + fTopHeight );
348 :
349 0 : double r1= 0.0, r2 = fRadius;
350 0 : if(bTopless)
351 : // #i63212# fHeight may be negative, fTopHeight is always positive -> use fabs(fHeight)
352 0 : r1 = fRadius * (fTopHeight)/(fabs(fHeight)+fTopHeight);
353 :
354 0 : nVerticalSegmentCount=1;
355 0 : drawing::PolyPolygonShape3D aPP;
356 :
357 0 : aPP.SequenceX.realloc(2);
358 0 : aPP.SequenceY.realloc(2);
359 0 : aPP.SequenceZ.realloc(2);
360 :
361 0 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
362 0 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
363 0 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
364 :
365 0 : pOuterSequenceX->realloc(2);
366 0 : pOuterSequenceY->realloc(2);
367 0 : pOuterSequenceZ->realloc(2);
368 :
369 0 : double* pInnerSequenceX = pOuterSequenceX->getArray();
370 0 : double* pInnerSequenceY = pOuterSequenceY->getArray();
371 0 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
372 :
373 0 : double fX1 = 0.0;
374 0 : double fX2 = r2;
375 0 : double fX3 = r1;
376 :
377 0 : double fY1 = 0.0;
378 0 : double fY2 = 0.0;
379 0 : double fY3 = fHeight;
380 :
381 0 : if( fHeight<0.0 )
382 : {
383 0 : ::std::swap(fX1,fX3);
384 0 : ::std::swap(fY1,fY3);
385 : }
386 :
387 : //----------------------------
388 0 : for(sal_Int32 nN = 2; nN--;)
389 0 : *pInnerSequenceZ++ = 0.0;
390 :
391 0 : *pInnerSequenceY++ = fY1;
392 0 : *pInnerSequenceX++ = fX1;
393 :
394 0 : *pInnerSequenceY++ = fY2;
395 0 : *pInnerSequenceX++ = fX2;
396 : //----------------------------
397 :
398 0 : pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++;
399 0 : pOuterSequenceX->realloc(2);
400 0 : pOuterSequenceY->realloc(2);
401 0 : pOuterSequenceZ->realloc(2);
402 :
403 0 : pInnerSequenceX = pOuterSequenceX->getArray();
404 0 : pInnerSequenceY = pOuterSequenceY->getArray();
405 0 : pInnerSequenceZ = pOuterSequenceZ->getArray();
406 :
407 : //----------------------------
408 0 : for(sal_Int32 nN = 2; nN--;)
409 0 : *pInnerSequenceZ++ = 0.0;
410 :
411 0 : *pInnerSequenceY++ = fY2;
412 0 : *pInnerSequenceX++ = fX2;
413 :
414 0 : *pInnerSequenceY++ = fY3;
415 0 : *pInnerSequenceX++ = fX3;
416 : //----------------------------
417 :
418 0 : return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) );
419 : }
420 :
421 : //-----------------------------------------------------------------------------
422 : //-----------------------------------------------------------------------------
423 : // methods for 3D shape creation
424 : //-----------------------------------------------------------------------------
425 : //-----------------------------------------------------------------------------
426 :
427 : uno::Reference<drawing::XShape>
428 0 : ShapeFactory::createCube(
429 : const uno::Reference<drawing::XShapes>& xTarget
430 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
431 : , sal_Int32 nRotateZAngleHundredthDegree
432 : , const uno::Reference< beans::XPropertySet >& xSourceProp
433 : , const tPropertyNameMap& rPropertyNameMap
434 : , bool bRounded )
435 : {
436 0 : if( !xTarget.is() )
437 0 : return 0;
438 0 : if( bRounded )
439 : {
440 : try
441 : {
442 0 : if( xSourceProp.is() )
443 : {
444 : drawing::LineStyle aLineStyle;
445 0 : xSourceProp->getPropertyValue( C2U( "BorderStyle" ) ) >>= aLineStyle;
446 0 : if( aLineStyle == drawing::LineStyle_SOLID )
447 0 : bRounded = false;
448 : }
449 : }
450 0 : catch( const uno::Exception& e )
451 : {
452 : ASSERT_EXCEPTION( e );
453 : }
454 : }
455 0 : uno::Reference<drawing::XShape> xShape = impl_createCube( xTarget, rPosition, rSize, nRotateZAngleHundredthDegree, bRounded );
456 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
457 0 : if( xSourceProp.is())
458 0 : PropertyMapper::setMappedProperties( xProp, xSourceProp, rPropertyNameMap );
459 0 : return xShape;
460 : }
461 :
462 : uno::Reference<drawing::XShape>
463 0 : ShapeFactory::impl_createCube(
464 : const uno::Reference<drawing::XShapes>& xTarget
465 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
466 : , sal_Int32 nRotateZAngleHundredthDegree
467 : , bool bRounded )
468 : {
469 0 : if( !xTarget.is() )
470 0 : return 0;
471 :
472 : //create shape
473 : uno::Reference< drawing::XShape > xShape(
474 0 : m_xShapeFactory->createInstance( C2U(
475 0 : "com.sun.star.drawing.Shape3DExtrudeObject") ), uno::UNO_QUERY );
476 0 : xTarget->add(xShape);
477 :
478 : //set properties
479 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
480 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
481 0 : if( xProp.is())
482 : {
483 : try
484 : {
485 : //depth
486 0 : double fDepth = rSize.DirectionZ;
487 0 : if(fDepth<0)
488 0 : fDepth*=-1.0;
489 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_EXTRUDE_DEPTH )
490 0 : , uno::makeAny((sal_Int32)fDepth) );
491 :
492 : //PercentDiagonal
493 0 : sal_Int16 nPercentDiagonal = bRounded ? 3 : 0;
494 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL )
495 0 : , uno::makeAny( nPercentDiagonal ) );
496 :
497 : //Polygon
498 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D )
499 0 : , createPolyPolygon_Cube( rSize, double(nPercentDiagonal)/200.0,bRounded) );
500 :
501 : //Matrix for position
502 : {
503 0 : ::basegfx::B3DHomMatrix aM;
504 0 : if(nRotateZAngleHundredthDegree!=0)
505 0 : aM.rotate(0.0,0.0,-nRotateZAngleHundredthDegree/18000.00*F_PI);
506 : aM.translate(rPosition.PositionX
507 : , rPosition.PositionY
508 0 : , rPosition.PositionZ - (fDepth/2.0));
509 0 : drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
510 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX )
511 0 : , uno::makeAny(aHM) );
512 : }
513 : }
514 0 : catch( const uno::Exception& e )
515 : {
516 : ASSERT_EXCEPTION( e );
517 : }
518 : }
519 0 : return xShape;
520 : }
521 :
522 : uno::Reference<drawing::XShape>
523 0 : ShapeFactory::createCylinder(
524 : const uno::Reference<drawing::XShapes>& xTarget
525 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
526 : , sal_Int32 nRotateZAngleHundredthDegree )
527 : {
528 : return impl_createConeOrCylinder(
529 0 : xTarget, rPosition, rSize, 0.0, nRotateZAngleHundredthDegree, true );
530 : }
531 :
532 : uno::Reference<drawing::XShape>
533 0 : ShapeFactory::createPyramid(
534 : const uno::Reference<drawing::XShapes>& xTarget
535 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
536 : , double fTopHeight, bool bRotateZ
537 : , const uno::Reference< beans::XPropertySet >& xSourceProp
538 : , const tPropertyNameMap& rPropertyNameMap )
539 : {
540 0 : if( !xTarget.is() )
541 0 : return 0;
542 :
543 0 : Reference< drawing::XShapes > xGroup( ShapeFactory::createGroup3D( xTarget, rtl::OUString() ) );
544 :
545 0 : sal_Bool bDoubleSided = false;
546 0 : short nRotatedTexture = 0;
547 :
548 0 : const double fWidth = rSize.DirectionX;
549 0 : const double fDepth = rSize.DirectionZ;
550 0 : const double fHeight = rSize.DirectionY;
551 :
552 0 : drawing::Position3D aBottomP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth/2.0 );
553 0 : if(bRotateZ)
554 0 : aBottomP1.PositionY -= fWidth/2.0;
555 : else
556 0 : aBottomP1.PositionX -= fWidth/2.0;
557 0 : drawing::Position3D aBottomP2( aBottomP1 );
558 0 : if(bRotateZ)
559 0 : aBottomP2.PositionY += fWidth;
560 : else
561 0 : aBottomP2.PositionX += fWidth;
562 0 : drawing::Position3D aBottomP3( aBottomP2 );
563 0 : drawing::Position3D aBottomP4( aBottomP1 );
564 0 : aBottomP3.PositionZ += fDepth;
565 0 : aBottomP4.PositionZ += fDepth;
566 :
567 0 : const double fTopFactor = (fTopHeight)/(fabs(fHeight)+fTopHeight);
568 0 : drawing::Position3D aTopP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth*fTopFactor/2.0 );
569 0 : if(bRotateZ)
570 : {
571 0 : aTopP1.PositionY -= fWidth*fTopFactor/2.0;
572 0 : aTopP1.PositionX += fHeight;
573 : }
574 : else
575 : {
576 0 : aTopP1.PositionX -= fWidth*fTopFactor/2.0;
577 0 : aTopP1.PositionY += fHeight;
578 : }
579 0 : drawing::Position3D aTopP2( aTopP1 );
580 0 : if(bRotateZ)
581 0 : aTopP2.PositionY += fWidth*fTopFactor;
582 : else
583 0 : aTopP2.PositionX += fWidth*fTopFactor;
584 0 : drawing::Position3D aTopP3( aTopP2 );
585 0 : drawing::Position3D aTopP4( aTopP1 );
586 0 : aTopP3.PositionZ += fDepth*fTopFactor;
587 0 : aTopP4.PositionZ += fDepth*fTopFactor;
588 :
589 0 : Stripe aStripeBottom( aBottomP1, aBottomP4, aBottomP3, aBottomP2 );
590 :
591 0 : drawing::Position3D aNormalsBottomP1( aBottomP1 );
592 0 : drawing::Position3D aNormalsBottomP2( aBottomP2 );
593 0 : drawing::Position3D aNormalsBottomP3( aBottomP3 );
594 0 : drawing::Position3D aNormalsBottomP4( aBottomP4 );
595 0 : drawing::Position3D aNormalsTopP1( aBottomP1 );
596 0 : drawing::Position3D aNormalsTopP2( aBottomP2 );
597 0 : drawing::Position3D aNormalsTopP3( aBottomP3 );
598 0 : drawing::Position3D aNormalsTopP4( aBottomP4 );
599 0 : if( bRotateZ )
600 : {
601 0 : aNormalsTopP1.PositionX += fHeight;
602 0 : aNormalsTopP2.PositionX += fHeight;
603 0 : aNormalsTopP3.PositionX += fHeight;
604 0 : aNormalsTopP4.PositionX += fHeight;
605 : }
606 : else
607 : {
608 0 : aNormalsTopP1.PositionY += fHeight;
609 0 : aNormalsTopP2.PositionY += fHeight;
610 0 : aNormalsTopP3.PositionY += fHeight;
611 0 : aNormalsTopP4.PositionY += fHeight;
612 : }
613 :
614 0 : bool bInvertPolygon = false;
615 0 : bool bInvertNormals = false;
616 :
617 0 : if(bRotateZ)
618 : {
619 : //bars
620 0 : if(fHeight>=0.0)
621 : {
622 0 : nRotatedTexture = 2;
623 0 : bInvertNormals = true;
624 0 : aStripeBottom = Stripe( aBottomP1, aBottomP4, aBottomP3, aBottomP2 );
625 : }
626 : else
627 : {
628 0 : bInvertPolygon = true;
629 0 : nRotatedTexture = 1;
630 0 : aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 );
631 : }
632 : }
633 : else
634 : {
635 : //columns
636 0 : if(fHeight>=0.0)
637 : {
638 0 : bInvertPolygon = true;
639 0 : nRotatedTexture = 2;
640 0 : aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 );
641 : }
642 : else
643 : {
644 0 : nRotatedTexture = 3;
645 0 : bInvertNormals = true;
646 0 : aStripeBottom = Stripe( aBottomP4, aBottomP3, aBottomP2, aBottomP1 );
647 : }
648 : }
649 0 : aStripeBottom.InvertNormal(true);
650 :
651 0 : Stripe aStripe1( aTopP2, aTopP1, aBottomP1, aBottomP2 );
652 0 : Stripe aStripe2( aTopP3, aTopP2, aBottomP2, aBottomP3 );
653 0 : Stripe aStripe3( aTopP4, aTopP3, aBottomP3, aBottomP4 );
654 0 : Stripe aStripe4( aTopP1, aTopP4, aBottomP4, aBottomP1 );
655 :
656 0 : if( bInvertPolygon )
657 : {
658 0 : aStripe1 = Stripe( aBottomP1, aTopP1, aTopP2, aBottomP2 );
659 0 : aStripe2 = Stripe( aBottomP2, aTopP2, aTopP3, aBottomP3 );
660 0 : aStripe3 = Stripe( aBottomP3, aTopP3, aTopP4, aBottomP4 );
661 0 : aStripe4 = Stripe( aBottomP4, aTopP4, aTopP1, aBottomP1 );
662 : }
663 :
664 0 : Stripe aNormalsStripe1( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP2, aNormalsTopP2 );
665 0 : Stripe aNormalsStripe2( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP3, aNormalsTopP3 );
666 0 : Stripe aNormalsStripe3( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP4, aNormalsTopP4 );
667 0 : Stripe aNormalsStripe4( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP1, aNormalsTopP1 );
668 :
669 0 : if( bInvertNormals )
670 : {
671 0 : aNormalsStripe1 = Stripe( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP1, aNormalsTopP1 );
672 0 : aNormalsStripe2 = Stripe( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP2, aNormalsTopP2 );
673 0 : aNormalsStripe3 = Stripe( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP3, aNormalsTopP3 );
674 0 : aNormalsStripe4 = Stripe( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP4, aNormalsTopP4 );
675 : }
676 :
677 0 : aStripe1.SetManualNormal( aNormalsStripe1.getNormal() );
678 0 : aStripe2.SetManualNormal( aNormalsStripe2.getNormal() );
679 0 : aStripe3.SetManualNormal( aNormalsStripe3.getNormal() );
680 0 : aStripe4.SetManualNormal( aNormalsStripe4.getNormal() );
681 :
682 0 : const bool bFlatNormals = false;
683 0 : ShapeFactory::createStripe( xGroup, aStripe1, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
684 0 : ShapeFactory::createStripe( xGroup, aStripe2, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
685 0 : ShapeFactory::createStripe( xGroup, aStripe3, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
686 0 : ShapeFactory::createStripe( xGroup, aStripe4, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
687 0 : ShapeFactory::createStripe( xGroup, aStripeBottom, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals );
688 :
689 0 : return Reference< drawing::XShape >( xGroup, uno::UNO_QUERY );
690 : }
691 :
692 : uno::Reference<drawing::XShape>
693 0 : ShapeFactory::createCone(
694 : const uno::Reference<drawing::XShapes>& xTarget
695 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
696 : , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree )
697 : {
698 0 : return impl_createConeOrCylinder( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree );
699 : }
700 :
701 : uno::Reference<drawing::XShape>
702 0 : ShapeFactory::impl_createConeOrCylinder(
703 : const uno::Reference<drawing::XShapes>& xTarget
704 : , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
705 : , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree
706 : , bool bCylinder )
707 : {
708 0 : if( !xTarget.is() )
709 0 : return 0;
710 :
711 : //create shape
712 : uno::Reference< drawing::XShape > xShape(
713 0 : m_xShapeFactory->createInstance( C2U(
714 0 : "com.sun.star.drawing.Shape3DLatheObject") ), uno::UNO_QUERY );
715 0 : xTarget->add(xShape);
716 :
717 0 : double fWidth = rSize.DirectionX/2.0; //The depth will be corrrected within Matrix
718 0 : double fRadius = fWidth; //!!!!!!!! problem in drawing layer: rotation object calculates wrong needed size -> wrong camera (it's a problem with bounding boxes)
719 0 : double fHeight = rSize.DirectionY;
720 :
721 : //set properties
722 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
723 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
724 0 : if( xProp.is())
725 : {
726 : try
727 : {
728 : //PercentDiagonal
729 0 : sal_Int16 nPercentDiagonal = 5;
730 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL )
731 0 : , uno::makeAny( nPercentDiagonal ) );
732 :
733 : //Polygon
734 0 : sal_Int32 nVerticalSegmentCount = 0;
735 : uno::Any aPPolygon = bCylinder ? createPolyPolygon_Cylinder(
736 : fHeight, fRadius, nVerticalSegmentCount)
737 : : createPolyPolygon_Cone(
738 0 : fHeight, fRadius, fTopHeight, nVerticalSegmentCount);
739 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D ), aPPolygon );
740 :
741 : //Matrix for position
742 : {
743 0 : ::basegfx::B3DHomMatrix aM;
744 0 : if(nRotateZAngleHundredthDegree!=0)
745 0 : aM.rotate(0.0,0.0,-nRotateZAngleHundredthDegree/18000.00*F_PI);
746 : //stretch the symmetric objects to given depth
747 0 : aM.scale(1.0,1.0,rSize.DirectionZ/rSize.DirectionX);
748 0 : aM.translate(rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ);
749 0 : drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
750 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX )
751 0 : , uno::makeAny(aHM) );
752 : }
753 :
754 : //Segments
755 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_HORZ_SEGS )
756 0 : , uno::makeAny(CHART_3DOBJECT_SEGMENTCOUNT) );
757 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_VERT_SEGS )
758 0 : , uno::makeAny((sal_Int32)nVerticalSegmentCount) );//depends on point count of the used polygon
759 :
760 : //Reduced lines
761 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_REDUCED_LINE_GEOMETRY )
762 0 : , uno::makeAny((sal_Bool)sal_True) );
763 : }
764 0 : catch( const uno::Exception& e )
765 : {
766 : ASSERT_EXCEPTION( e );
767 : }
768 : }
769 0 : return xShape;
770 : }
771 :
772 : //------------------------------------------------------------------------------------------------------------
773 : //------------------------------------------------------------------------------------------------------------
774 : //------------------------------------------------------------------------------------------------------------
775 :
776 0 : void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords& rReturn, const drawing::PolyPolygonBezierCoords& rAdd, sal_Bool bAppendInverse )
777 : {
778 0 : if(!rAdd.Coordinates.getLength())
779 0 : return;
780 0 : sal_Int32 nAddCount = rAdd.Coordinates[0].getLength();
781 0 : if(!nAddCount)
782 0 : return;
783 :
784 0 : sal_Int32 nOldCount = rReturn.Coordinates[0].getLength();
785 :
786 0 : rReturn.Coordinates[0].realloc(nOldCount+nAddCount+1);
787 0 : rReturn.Flags[0].realloc(nOldCount+nAddCount+1);
788 :
789 0 : for(sal_Int32 nN=0;nN<nAddCount; nN++ )
790 : {
791 0 : sal_Int32 nAdd = bAppendInverse ? (nAddCount-1-nN) : nN;
792 0 : rReturn.Coordinates[0][nOldCount+nN] = rAdd.Coordinates[0][nAdd];
793 0 : rReturn.Flags[0][nOldCount+nN] = rAdd.Flags[0][nAdd];
794 : }
795 :
796 : //close
797 0 : rReturn.Coordinates[0][nOldCount+nAddCount] = rReturn.Coordinates[0][0];
798 0 : rReturn.Flags[0][nOldCount+nAddCount] = rReturn.Flags[0][0];
799 : }
800 :
801 : //------------------------------------------------------------------------------------------------------------
802 :
803 0 : drawing::PolyPolygonBezierCoords getCircularArcBezierCoords(
804 : double fStartAngleRadian, double fWidthAngleRadian, double fUnitRadius
805 : , const ::basegfx::B2DHomMatrix& rTransformationFromUnitCircle
806 : , const double fAngleSubdivisionRadian )
807 : {
808 : //at least one polygon is created using two normal and two control points
809 : //if the angle is larger it is separated into multiple sub angles
810 :
811 0 : drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
812 0 : sal_Int32 nSegmentCount = static_cast< sal_Int32 >( fWidthAngleRadian/fAngleSubdivisionRadian );
813 0 : if( fWidthAngleRadian > fAngleSubdivisionRadian*nSegmentCount )
814 0 : nSegmentCount++;
815 :
816 0 : double fFirstSegmentAngle = fAngleSubdivisionRadian;
817 0 : double fLastSegmentAngle = fAngleSubdivisionRadian;
818 0 : if(nSegmentCount==1)
819 : {
820 0 : fFirstSegmentAngle = fWidthAngleRadian;
821 0 : fLastSegmentAngle = 0.0;
822 : }
823 : else
824 : {
825 0 : double fFirstAngleOnSubDevision = (static_cast<sal_Int32>(fStartAngleRadian/fAngleSubdivisionRadian)+1)*fAngleSubdivisionRadian;
826 0 : if( !::rtl::math::approxEqual( fStartAngleRadian, fFirstAngleOnSubDevision ) )
827 0 : fFirstSegmentAngle = fFirstAngleOnSubDevision-fStartAngleRadian;
828 :
829 0 : if(nSegmentCount>1)
830 : {
831 0 : fLastSegmentAngle = fWidthAngleRadian-fFirstSegmentAngle-fAngleSubdivisionRadian*(nSegmentCount-2);
832 0 : if( fLastSegmentAngle<0 )
833 0 : nSegmentCount--;
834 0 : if( fLastSegmentAngle>fAngleSubdivisionRadian )
835 : {
836 0 : fLastSegmentAngle-=fAngleSubdivisionRadian;
837 0 : nSegmentCount++;
838 : }
839 : }
840 : }
841 :
842 0 : sal_Int32 nPointCount = 1 + 3*nSegmentCount; //first point of next segment equals last point of former segment
843 :
844 0 : aReturn.Coordinates = drawing::PointSequenceSequence(1);
845 0 : aReturn.Flags = drawing::FlagSequenceSequence(1);
846 :
847 0 : drawing::PointSequence aPoints(nPointCount);
848 0 : drawing::FlagSequence aFlags(nPointCount);
849 :
850 : //
851 :
852 : //!! applying matrix to vector does ignore translation, so it is important to use a B2DPoint here instead of B2DVector
853 0 : ::basegfx::B2DPoint P0,P1,P2,P3;
854 0 : ::basegfx::B2DPoint POrigin = rTransformationFromUnitCircle * ::basegfx::B2DPoint(0.0, 0.0);
855 :
856 0 : sal_Int32 nPoint=0;
857 0 : double fCurrentRotateAngle = fStartAngleRadian;
858 0 : for(sal_Int32 nSegment=0; nSegment<nSegmentCount; nSegment++)
859 : {
860 0 : double fCurrentSegmentAngle = fAngleSubdivisionRadian;
861 0 : if(nSegment==0)//first segment gets only a smaller peace until the next subdevision
862 0 : fCurrentSegmentAngle = fFirstSegmentAngle;
863 0 : else if(nSegment==(nSegmentCount-1)) //the last segment gets the rest angle that does not fit into equal pieces
864 0 : fCurrentSegmentAngle = fLastSegmentAngle;
865 :
866 : //first create untransformed points for a unit circle arc:
867 0 : const double fCos = cos(fCurrentSegmentAngle/2.0);
868 0 : const double fSin = sin(fCurrentSegmentAngle/2.0);
869 0 : P0.setX(fCos);
870 0 : P3.setX(fCos);
871 0 : P0.setY(-fSin);
872 0 : P3.setY(-P0.getY());
873 :
874 0 : P1.setX((4.0-fCos)/3.0);
875 0 : P2.setX(P1.getX());
876 0 : P1.setY((1.0-fCos)*(fCos-3.0)/(3.0*fSin));
877 0 : P2.setY(-P1.getY());
878 : //transform thus startangle equals NULL
879 0 : ::basegfx::B2DHomMatrix aStart;
880 0 : aStart.rotate(fCurrentSegmentAngle/2.0 + fCurrentRotateAngle );
881 0 : fCurrentRotateAngle+=fCurrentSegmentAngle;
882 :
883 0 : aStart.scale( fUnitRadius, fUnitRadius );
884 :
885 : //apply given transformation to get final points
886 0 : P0 = rTransformationFromUnitCircle*(aStart*P0);
887 0 : P1 = rTransformationFromUnitCircle*(aStart*P1);
888 0 : P2 = rTransformationFromUnitCircle*(aStart*P2);
889 0 : P3 = rTransformationFromUnitCircle*(aStart*P3);
890 :
891 0 : aPoints[nPoint].X = static_cast< sal_Int32 >( P0.getX());
892 0 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P0.getY());
893 0 : aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
894 :
895 0 : aPoints[nPoint].X = static_cast< sal_Int32 >( P1.getX());
896 0 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P1.getY());
897 0 : aFlags[nPoint++] = drawing::PolygonFlags_CONTROL;
898 :
899 0 : aPoints[nPoint].X = static_cast< sal_Int32 >( P2.getX());
900 0 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P2.getY());
901 0 : aFlags [nPoint++] = drawing::PolygonFlags_CONTROL;
902 :
903 0 : if(nSegment==(nSegmentCount-1))
904 : {
905 0 : aPoints[nPoint].X = static_cast< sal_Int32 >( P3.getX());
906 0 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P3.getY());
907 0 : aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
908 : }
909 0 : }
910 :
911 0 : aReturn.Coordinates[0] = aPoints;
912 0 : aReturn.Flags[0] = aFlags;
913 :
914 0 : return aReturn;
915 : }
916 :
917 : //------------------------------------------------------------------------------------------------------------
918 :
919 0 : drawing::PolyPolygonBezierCoords getRingBezierCoords(
920 : double fUnitCircleInnerRadius
921 : , double fUnitCircleOuterRadius
922 : , double fStartAngleRadian, double fWidthAngleRadian
923 : , ::basegfx::B2DHomMatrix aTransformationFromUnitCircle
924 : , const double fAngleSubdivisionRadian )
925 : {
926 0 : drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
927 :
928 0 : aReturn.Coordinates = drawing::PointSequenceSequence(1);
929 0 : aReturn.Flags = drawing::FlagSequenceSequence(1);
930 :
931 : drawing::PolyPolygonBezierCoords aOuterArc = getCircularArcBezierCoords(
932 0 : fStartAngleRadian, fWidthAngleRadian, fUnitCircleOuterRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
933 0 : aReturn.Coordinates[0] = aOuterArc.Coordinates[0];
934 0 : aReturn.Flags[0] = aOuterArc.Flags[0];
935 :
936 : drawing::PolyPolygonBezierCoords aInnerArc = getCircularArcBezierCoords(
937 0 : fStartAngleRadian, fWidthAngleRadian, fUnitCircleInnerRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
938 0 : appendAndCloseBezierCoords( aReturn, aInnerArc, sal_True );
939 :
940 0 : return aReturn;
941 : }
942 :
943 : //------------------------------------------------------------------------------------------------------------
944 :
945 : uno::Reference< drawing::XShape >
946 0 : ShapeFactory::createPieSegment2D(
947 : const uno::Reference< drawing::XShapes >& xTarget
948 : , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
949 : , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
950 : , const drawing::Direction3D& rOffset
951 : , const drawing::HomogenMatrix& rUnitCircleToScene )
952 : {
953 0 : if( !xTarget.is() )
954 0 : return 0;
955 :
956 0 : while(fUnitCircleWidthAngleDegree>360)
957 0 : fUnitCircleWidthAngleDegree -= 360.0;
958 0 : while(fUnitCircleWidthAngleDegree<0)
959 0 : fUnitCircleWidthAngleDegree += 360.0;
960 :
961 : //create shape
962 : uno::Reference< drawing::XShape > xShape(
963 0 : m_xShapeFactory->createInstance(
964 0 : C2U("com.sun.star.drawing.ClosedBezierShape") ), uno::UNO_QUERY );
965 0 : xTarget->add(xShape); //need to add the shape before setting of properties
966 :
967 : //set properties
968 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
969 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
970 0 : if( xProp.is())
971 : {
972 : try
973 : {
974 0 : ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
975 0 : aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
976 :
977 0 : const double fAngleSubdivisionRadian = F_PI/10.0;
978 :
979 : drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
980 : fUnitCircleInnerRadius, fUnitCircleOuterRadius
981 : , fUnitCircleStartAngleDegree*F_PI/180.0, fUnitCircleWidthAngleDegree*F_PI/180.0
982 0 : , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
983 :
984 0 : xProp->setPropertyValue( C2U( "PolyPolygonBezier" ), uno::makeAny( aCoords ) );
985 : }
986 0 : catch( const uno::Exception& e )
987 : {
988 : ASSERT_EXCEPTION( e );
989 : }
990 : }
991 :
992 0 : return xShape;
993 : }
994 :
995 : //------------------------------------------------------------------------------------------------------------
996 :
997 : uno::Reference< drawing::XShape >
998 0 : ShapeFactory::createPieSegment(
999 : const uno::Reference< drawing::XShapes >& xTarget
1000 : , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
1001 : , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
1002 : , const drawing::Direction3D& rOffset
1003 : , const drawing::HomogenMatrix& rUnitCircleToScene
1004 : , double fDepth )
1005 : {
1006 0 : if( !xTarget.is() )
1007 0 : return 0;
1008 :
1009 0 : while(fUnitCircleWidthAngleDegree>360)
1010 0 : fUnitCircleWidthAngleDegree -= 360.0;
1011 0 : while(fUnitCircleWidthAngleDegree<0)
1012 0 : fUnitCircleWidthAngleDegree += 360.0;
1013 :
1014 : //create shape
1015 : uno::Reference< drawing::XShape > xShape(
1016 0 : m_xShapeFactory->createInstance( C2U(
1017 0 : "com.sun.star.drawing.Shape3DExtrudeObject") ), uno::UNO_QUERY );
1018 0 : xTarget->add(xShape); //need to add the shape before setting of properties
1019 :
1020 : //set properties
1021 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1022 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1023 0 : if( xProp.is())
1024 : {
1025 : try
1026 : {
1027 0 : ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
1028 0 : aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
1029 :
1030 0 : const double fAngleSubdivisionRadian = F_PI/32.0;
1031 :
1032 : drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
1033 : fUnitCircleInnerRadius, fUnitCircleOuterRadius
1034 : , fUnitCircleStartAngleDegree*F_PI/180.0, fUnitCircleWidthAngleDegree*F_PI/180.0
1035 0 : , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
1036 :
1037 : //depth
1038 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_EXTRUDE_DEPTH )
1039 0 : , uno::makeAny((sal_Int32)fDepth) );
1040 :
1041 : //PercentDiagonal
1042 0 : sal_Int16 nPercentDiagonal = 0;
1043 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL )
1044 0 : , uno::makeAny( nPercentDiagonal ) );
1045 :
1046 : //Polygon
1047 0 : drawing::PolyPolygonShape3D aPoly( BezierToPoly(aCoords) );
1048 0 : ShapeFactory::closePolygon( aPoly );
1049 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D )
1050 0 : , uno::makeAny( aPoly ) );
1051 :
1052 : //DoubleSided
1053 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_DOUBLE_SIDED )
1054 0 : , uno::makeAny( (sal_Bool)true) );
1055 :
1056 : //Reduced lines
1057 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_REDUCED_LINE_GEOMETRY )
1058 0 : , uno::makeAny((sal_Bool)sal_True) );
1059 :
1060 : //TextureProjectionMode
1061 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTURE_PROJ_Y )
1062 0 : , uno::makeAny( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
1063 :
1064 : //TextureProjectionMode
1065 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTURE_PROJ_X )
1066 0 : , uno::makeAny( drawing::TextureProjectionMode_PARALLEL ) );
1067 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTURE_PROJ_Y )
1068 0 : , uno::makeAny( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
1069 : }
1070 0 : catch( const uno::Exception& e )
1071 : {
1072 : ASSERT_EXCEPTION( e );
1073 : }
1074 : }
1075 0 : return xShape;
1076 : }
1077 :
1078 : //------------------------------------------------------------------------------------------------------------
1079 : //------------------------------------------------------------------------------------------------------------
1080 : //------------------------------------------------------------------------------------------------------------
1081 :
1082 : uno::Reference< drawing::XShape >
1083 0 : ShapeFactory::createStripe( const uno::Reference< drawing::XShapes >& xTarget
1084 : , const Stripe& rStripe
1085 : , const uno::Reference< beans::XPropertySet >& xSourceProp
1086 : , const tPropertyNameMap& rPropertyNameMap
1087 : , sal_Bool bDoubleSided
1088 : , short nRotatedTexture
1089 : , bool bFlatNormals )
1090 : {
1091 0 : if( !xTarget.is() )
1092 0 : return 0;
1093 :
1094 : //create shape
1095 : uno::Reference< drawing::XShape > xShape(
1096 0 : m_xShapeFactory->createInstance( C2U(
1097 0 : "com.sun.star.drawing.Shape3DPolygonObject" ) ), uno::UNO_QUERY );
1098 0 : xTarget->add(xShape);
1099 :
1100 : //set properties
1101 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1102 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1103 0 : if( xProp.is())
1104 : {
1105 : try
1106 : {
1107 : //Polygon
1108 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D )
1109 0 : , rStripe.getPolyPolygonShape3D() );
1110 :
1111 : //TexturePolygon
1112 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTUREPOLYGON3D )
1113 0 : , rStripe.getTexturePolygon( nRotatedTexture ) );
1114 :
1115 : //Normals Polygon
1116 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_NORMALSPOLYGON3D )
1117 0 : , rStripe.getNormalsPolygon() );
1118 : //NormalsKind
1119 0 : if(bFlatNormals)
1120 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_NORMALS_KIND )
1121 0 : , uno::makeAny( drawing::NormalsKind_FLAT ) );
1122 :
1123 : //LineOnly
1124 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_LINEONLY )
1125 0 : , uno::makeAny( (sal_Bool)false) );
1126 :
1127 : //DoubleSided
1128 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_DOUBLE_SIDED )
1129 0 : , uno::makeAny(bDoubleSided) );
1130 :
1131 0 : if( xSourceProp.is())
1132 0 : PropertyMapper::setMappedProperties( xProp, xSourceProp, rPropertyNameMap );
1133 : }
1134 0 : catch( const uno::Exception& e )
1135 : {
1136 : ASSERT_EXCEPTION( e );
1137 : }
1138 : }
1139 0 : return xShape;
1140 : }
1141 :
1142 : uno::Reference< drawing::XShape >
1143 0 : ShapeFactory::createArea3D( const uno::Reference< drawing::XShapes >& xTarget
1144 : , const drawing::PolyPolygonShape3D& rPolyPolygon
1145 : , double fDepth )
1146 : {
1147 0 : if( !xTarget.is() )
1148 0 : return 0;
1149 :
1150 0 : if( !rPolyPolygon.SequenceX.getLength())
1151 0 : return 0;
1152 :
1153 : //create shape
1154 : uno::Reference< drawing::XShape > xShape(
1155 0 : m_xShapeFactory->createInstance( C2U(
1156 0 : "com.sun.star.drawing.Shape3DExtrudeObject") ), uno::UNO_QUERY );
1157 0 : xTarget->add(xShape);
1158 :
1159 : //set properties
1160 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1161 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1162 0 : if( xProp.is())
1163 : {
1164 : try
1165 : {
1166 : //depth
1167 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_EXTRUDE_DEPTH )
1168 0 : , uno::makeAny((sal_Int32)fDepth) );
1169 :
1170 : //PercentDiagonal
1171 0 : sal_Int16 nPercentDiagonal = 0;
1172 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL )
1173 0 : , uno::makeAny( nPercentDiagonal ) );
1174 :
1175 : //Polygon
1176 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D )
1177 0 : , uno::makeAny( rPolyPolygon ) );
1178 :
1179 : //DoubleSided
1180 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_DOUBLE_SIDED )
1181 0 : , uno::makeAny( (sal_Bool)true) );
1182 :
1183 : //the z component of the polygon is now ignored by the drawing layer,
1184 : //so we nned to translate the object via transformation matrix
1185 :
1186 : //Matrix for position
1187 0 : if( rPolyPolygon.SequenceZ.getLength()&& rPolyPolygon.SequenceZ[0].getLength() )
1188 : {
1189 0 : ::basegfx::B3DHomMatrix aM;
1190 : aM.translate( 0
1191 : , 0
1192 0 : , rPolyPolygon.SequenceZ[0][0] );
1193 0 : drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
1194 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX )
1195 0 : , uno::makeAny(aHM) );
1196 : }
1197 : }
1198 0 : catch( const uno::Exception& e )
1199 : {
1200 : ASSERT_EXCEPTION( e );
1201 : }
1202 : }
1203 0 : return xShape;
1204 : }
1205 :
1206 : uno::Reference< drawing::XShape >
1207 492 : ShapeFactory::createArea2D( const uno::Reference< drawing::XShapes >& xTarget
1208 : , const drawing::PolyPolygonShape3D& rPolyPolygon )
1209 : {
1210 492 : if( !xTarget.is() )
1211 0 : return 0;
1212 :
1213 : //create shape
1214 : uno::Reference< drawing::XShape > xShape(
1215 492 : m_xShapeFactory->createInstance( C2U(
1216 492 : "com.sun.star.drawing.PolyPolygonShape") ), uno::UNO_QUERY );
1217 492 : xTarget->add(xShape);
1218 :
1219 : //set properties
1220 492 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1221 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1222 492 : if( xProp.is())
1223 : {
1224 : try
1225 : {
1226 : //UNO_NAME_POLYGON "Polygon" drawing::PointSequence*
1227 492 : drawing::PointSequenceSequence aPoints( PolyToPointSequence(rPolyPolygon) );
1228 :
1229 : //Polygon
1230 492 : xProp->setPropertyValue( C2U( UNO_NAME_POLYPOLYGON )
1231 492 : , uno::makeAny( aPoints ) );
1232 :
1233 : //ZOrder
1234 : //an area should always be behind other shapes
1235 492 : xProp->setPropertyValue( C2U( UNO_NAME_MISC_OBJ_ZORDER )
1236 492 : , uno::makeAny( sal_Int32(0) ) );
1237 : }
1238 0 : catch( const uno::Exception& e )
1239 : {
1240 : ASSERT_EXCEPTION( e );
1241 : }
1242 : }
1243 492 : return xShape;
1244 : }
1245 :
1246 : enum SymbolType { SYMBOL_SQUARE=0
1247 : , SYMBOL_DIAMOND
1248 : , SYMBOL_ARROW_DOWN
1249 : , SYMBOL_ARROW_UP
1250 : , SYMBOL_ARROW_RIGHT
1251 : , SYMBOL_ARROW_LEFT
1252 : , SYMBOL_BOWTIE
1253 : , SYMBOL_SANDGLASS
1254 : , SYMBOL_CIRCLE
1255 : , SYMBOL_STAR
1256 : , SYMBOL_X
1257 : , SYMBOL_PLUS
1258 : , SYMBOL_ASTERISK
1259 : , SYMBOL_HORIZONTAL_BAR
1260 : , SYMBOL_VERTICAL_BAR
1261 : , SYMBOL_COUNT
1262 : };
1263 :
1264 0 : sal_Int32 ShapeFactory::getSymbolCount()
1265 : {
1266 0 : return SYMBOL_COUNT;
1267 : }
1268 :
1269 0 : drawing::PolyPolygonShape3D createPolyPolygon_Symbol( const drawing::Position3D& rPos
1270 : , const drawing::Direction3D& rSize
1271 : , sal_Int32 nStandardSymbol )
1272 : {
1273 0 : if(nStandardSymbol<0)
1274 0 : nStandardSymbol*=-1;
1275 0 : nStandardSymbol = nStandardSymbol%ShapeFactory::getSymbolCount();
1276 0 : SymbolType eSymbolType=static_cast<SymbolType>(nStandardSymbol);
1277 :
1278 0 : const double& fX = rPos.PositionX;
1279 0 : const double& fY = rPos.PositionY;
1280 :
1281 0 : const double fWidthH = rSize.DirectionX/2.0; //fWidthH stands for Half Width
1282 0 : const double fHeightH = rSize.DirectionY/2.0; //fHeightH stands for Half Height
1283 :
1284 0 : const sal_Int32 nQuarterCount = 35; // points inside a quadrant, used in case circle
1285 :
1286 0 : sal_Int32 nPointCount = 4; //all arrow symbols only need 4 points
1287 0 : switch( eSymbolType )
1288 : {
1289 : case SYMBOL_SQUARE:
1290 : case SYMBOL_DIAMOND:
1291 : case SYMBOL_BOWTIE:
1292 : case SYMBOL_SANDGLASS:
1293 : case SYMBOL_HORIZONTAL_BAR:
1294 : case SYMBOL_VERTICAL_BAR:
1295 0 : nPointCount = 5;
1296 0 : break;
1297 : case SYMBOL_X:
1298 0 : nPointCount = 13;
1299 0 : break;
1300 : case SYMBOL_PLUS:
1301 0 : nPointCount = 13;
1302 0 : break;
1303 : case SYMBOL_STAR:
1304 0 : nPointCount = 9;
1305 0 : break;
1306 : case SYMBOL_ASTERISK:
1307 0 : nPointCount = 19;
1308 0 : break;
1309 : case SYMBOL_CIRCLE:
1310 0 : nPointCount = 5 + 4 * nQuarterCount;
1311 0 : break;
1312 : default:
1313 0 : break;
1314 : }
1315 :
1316 : //--------------------------------------
1317 0 : drawing::PolyPolygonShape3D aPP;
1318 :
1319 0 : aPP.SequenceX.realloc(1);
1320 0 : aPP.SequenceY.realloc(1);
1321 0 : aPP.SequenceZ.realloc(1);
1322 :
1323 0 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
1324 0 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
1325 0 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
1326 :
1327 0 : pOuterSequenceX->realloc(nPointCount);
1328 0 : pOuterSequenceY->realloc(nPointCount);
1329 0 : pOuterSequenceZ->realloc(nPointCount);
1330 :
1331 0 : double* pInnerSequenceX = pOuterSequenceX->getArray();
1332 0 : double* pInnerSequenceY = pOuterSequenceY->getArray();
1333 0 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
1334 :
1335 0 : for(sal_Int32 nN = nPointCount; nN--;)
1336 0 : *pInnerSequenceZ++ = 0.0;
1337 :
1338 0 : switch(eSymbolType)
1339 : {
1340 : case SYMBOL_SQUARE:
1341 : {
1342 0 : *pInnerSequenceX++ = fX-fWidthH;
1343 0 : *pInnerSequenceY++ = fY-fHeightH;
1344 :
1345 0 : *pInnerSequenceX++ = fX-fWidthH;
1346 0 : *pInnerSequenceY++ = fY+fHeightH;
1347 :
1348 0 : *pInnerSequenceX++ = fX+fWidthH;
1349 0 : *pInnerSequenceY++ = fY+fHeightH;
1350 :
1351 0 : *pInnerSequenceX++ = fX+fWidthH;
1352 0 : *pInnerSequenceY++ = fY-fHeightH;
1353 :
1354 0 : *pInnerSequenceX++ = fX-fWidthH;
1355 0 : *pInnerSequenceY++ = fY-fHeightH;
1356 0 : break;
1357 : }
1358 : case SYMBOL_ARROW_UP:
1359 : {
1360 0 : *pInnerSequenceX++ = fX-fWidthH;
1361 0 : *pInnerSequenceY++ = fY+fHeightH;
1362 :
1363 0 : *pInnerSequenceX++ = fX+fWidthH;
1364 0 : *pInnerSequenceY++ = fY+fHeightH;
1365 :
1366 0 : *pInnerSequenceX++ = fX;
1367 0 : *pInnerSequenceY++ = fY-fHeightH;
1368 :
1369 0 : *pInnerSequenceX++ = fX-fWidthH;
1370 0 : *pInnerSequenceY++ = fY+fHeightH;
1371 0 : break;
1372 : }
1373 : case SYMBOL_ARROW_DOWN:
1374 : {
1375 0 : *pInnerSequenceX++ = fX-fWidthH;
1376 0 : *pInnerSequenceY++ = fY-fHeightH;
1377 :
1378 0 : *pInnerSequenceX++ = fX;
1379 0 : *pInnerSequenceY++ = fY+fHeightH;
1380 :
1381 0 : *pInnerSequenceX++ = fX+fWidthH;
1382 0 : *pInnerSequenceY++ = fY-fHeightH;
1383 :
1384 0 : *pInnerSequenceX++ = fX-fWidthH;
1385 0 : *pInnerSequenceY++ = fY-fHeightH;
1386 0 : break;
1387 : }
1388 : case SYMBOL_ARROW_RIGHT:
1389 : {
1390 0 : *pInnerSequenceX++ = fX-fWidthH;
1391 0 : *pInnerSequenceY++ = fY-fHeightH;
1392 :
1393 0 : *pInnerSequenceX++ = fX-fWidthH;
1394 0 : *pInnerSequenceY++ = fY+fHeightH;
1395 :
1396 0 : *pInnerSequenceX++ = fX+fWidthH;
1397 0 : *pInnerSequenceY++ = fY;
1398 :
1399 0 : *pInnerSequenceX++ = fX-fWidthH;
1400 0 : *pInnerSequenceY++ = fY-fHeightH;
1401 0 : break;
1402 : }
1403 : case SYMBOL_ARROW_LEFT:
1404 : {
1405 0 : *pInnerSequenceX++ = fX-fWidthH;
1406 0 : *pInnerSequenceY++ = fY;
1407 :
1408 0 : *pInnerSequenceX++ = fX+fWidthH;
1409 0 : *pInnerSequenceY++ = fY+fHeightH;
1410 :
1411 0 : *pInnerSequenceX++ = fX+fWidthH;
1412 0 : *pInnerSequenceY++ = fY-fHeightH;
1413 :
1414 0 : *pInnerSequenceX++ = fX-fWidthH;
1415 0 : *pInnerSequenceY++ = fY;
1416 0 : break;
1417 : }
1418 : case SYMBOL_BOWTIE:
1419 : {
1420 0 : *pInnerSequenceX++ = fX-fWidthH;
1421 0 : *pInnerSequenceY++ = fY-fHeightH;
1422 :
1423 0 : *pInnerSequenceX++ = fX-fWidthH;
1424 0 : *pInnerSequenceY++ = fY+fHeightH;
1425 :
1426 0 : *pInnerSequenceX++ = fX+fWidthH;
1427 0 : *pInnerSequenceY++ = fY-fHeightH;
1428 :
1429 0 : *pInnerSequenceX++ = fX+fWidthH;
1430 0 : *pInnerSequenceY++ = fY+fHeightH;
1431 :
1432 0 : *pInnerSequenceX++ = fX-fWidthH;
1433 0 : *pInnerSequenceY++ = fY-fHeightH;
1434 0 : break;
1435 : }
1436 : case SYMBOL_SANDGLASS:
1437 : {
1438 0 : *pInnerSequenceX++ = fX-fWidthH;
1439 0 : *pInnerSequenceY++ = fY+fHeightH;
1440 :
1441 0 : *pInnerSequenceX++ = fX+fWidthH;
1442 0 : *pInnerSequenceY++ = fY+fHeightH;
1443 :
1444 0 : *pInnerSequenceX++ = fX-fWidthH;
1445 0 : *pInnerSequenceY++ = fY-fHeightH;
1446 :
1447 :
1448 0 : *pInnerSequenceX++ = fX+fWidthH;
1449 0 : *pInnerSequenceY++ = fY-fHeightH;
1450 :
1451 0 : *pInnerSequenceX++ = fX-fWidthH;
1452 0 : *pInnerSequenceY++ = fY+fHeightH;
1453 0 : break;
1454 : }
1455 : case SYMBOL_DIAMOND:
1456 : {
1457 0 : *pInnerSequenceX++ = fX-fWidthH;
1458 0 : *pInnerSequenceY++ = fY;
1459 :
1460 0 : *pInnerSequenceX++ = fX;
1461 0 : *pInnerSequenceY++ = fY+fHeightH;
1462 :
1463 0 : *pInnerSequenceX++ = fX+fWidthH;
1464 0 : *pInnerSequenceY++ = fY;
1465 :
1466 0 : *pInnerSequenceX++ = fX;
1467 0 : *pInnerSequenceY++ = fY-fHeightH;
1468 :
1469 0 : *pInnerSequenceX++ = fX-fWidthH;
1470 0 : *pInnerSequenceY++ = fY;
1471 0 : break;
1472 : }
1473 : case SYMBOL_HORIZONTAL_BAR:
1474 : {
1475 0 : *pInnerSequenceX++ = fX-fWidthH;
1476 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1477 :
1478 0 : *pInnerSequenceX++ = fX+fWidthH;
1479 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1480 :
1481 :
1482 0 : *pInnerSequenceX++ = fX+fWidthH;
1483 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1484 :
1485 0 : *pInnerSequenceX++ = fX-fWidthH;
1486 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1487 :
1488 0 : *pInnerSequenceX++ = fX-fWidthH;
1489 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1490 0 : break;
1491 : }
1492 : case SYMBOL_VERTICAL_BAR:
1493 : {
1494 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1495 0 : *pInnerSequenceY++ = fY-fHeightH;
1496 :
1497 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1498 0 : *pInnerSequenceY++ = fY-fHeightH;
1499 :
1500 :
1501 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1502 0 : *pInnerSequenceY++ = fY+fHeightH;
1503 :
1504 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1505 0 : *pInnerSequenceY++ = fY+fHeightH;
1506 :
1507 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1508 0 : *pInnerSequenceY++ = fY-fHeightH;
1509 :
1510 0 : break;
1511 : }
1512 : case SYMBOL_CIRCLE:
1513 : {
1514 0 : double fOmega = 1.5707963267948966192 / (nQuarterCount + 1.0);
1515 : // one point in the middle of each edge to get full size bounding rectangle
1516 0 : *pInnerSequenceX++ = fX + fWidthH;
1517 0 : *pInnerSequenceY++ = fY;
1518 : // 0 to PI/2
1519 0 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1520 : {
1521 0 : *pInnerSequenceX++ = fX + fWidthH * cos( i * fOmega );
1522 0 : *pInnerSequenceY++ = fY - fHeightH * sin( i * fOmega );
1523 : }
1524 : // PI/2 to PI
1525 0 : *pInnerSequenceX++ = fX;
1526 0 : *pInnerSequenceY++ = fY - fHeightH;
1527 0 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1528 : {
1529 0 : *pInnerSequenceX++ = fX - fWidthH * sin( i * fOmega);
1530 0 : *pInnerSequenceY++ = fY - fHeightH * cos( i * fOmega);
1531 : }
1532 : // PI to 3/2*PI
1533 0 : *pInnerSequenceX++ = fX - fWidthH;
1534 0 : *pInnerSequenceY++ = fY;
1535 0 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1536 : {
1537 0 : *pInnerSequenceX++ = fX - fWidthH * cos( i * fOmega);
1538 0 : *pInnerSequenceY++ = fY + fHeightH * sin( i * fOmega);
1539 : }
1540 : // 3/2*PI to 2*PI
1541 0 : *pInnerSequenceX++ = fX;
1542 0 : *pInnerSequenceY++ = fY + fHeightH;
1543 0 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1544 : {
1545 0 : *pInnerSequenceX++ = fX + fWidthH * sin(i * fOmega);
1546 0 : *pInnerSequenceY++ = fY + fHeightH * cos(i * fOmega);
1547 : }
1548 : // close polygon
1549 0 : *pInnerSequenceX++ = fX + fWidthH;
1550 0 : *pInnerSequenceY++ = fY;
1551 0 : break;
1552 : }
1553 : case SYMBOL_STAR:
1554 : {
1555 0 : *pInnerSequenceX++ = fX;
1556 0 : *pInnerSequenceY++ = fY-fHeightH;
1557 :
1558 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1559 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1560 :
1561 0 : *pInnerSequenceX++ = fX+fWidthH;
1562 0 : *pInnerSequenceY++ = fY;
1563 :
1564 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1565 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1566 :
1567 0 : *pInnerSequenceX++ = fX;
1568 0 : *pInnerSequenceY++ = fY+fHeightH;
1569 :
1570 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1571 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1572 :
1573 0 : *pInnerSequenceX++ = fX-fWidthH;
1574 0 : *pInnerSequenceY++ = fY;
1575 :
1576 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1577 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1578 :
1579 0 : *pInnerSequenceX++ = fX;
1580 0 : *pInnerSequenceY++ = fY-fHeightH;
1581 0 : break;
1582 : }
1583 : case SYMBOL_X:
1584 : {
1585 0 : const double fScaleX = fWidthH / 128.0;
1586 0 : const double fScaleY = fHeightH / 128.0;
1587 0 : const double fSmall = sqrt(200.0);
1588 0 : const double fLarge = 128.0 - fSmall;
1589 :
1590 0 : *pInnerSequenceX++ = fX;
1591 0 : *pInnerSequenceY++ = fY - fScaleY * fSmall;
1592 :
1593 0 : *pInnerSequenceX++ = fX - fScaleX * fLarge;
1594 0 : *pInnerSequenceY++ = fY - fHeightH;
1595 :
1596 0 : *pInnerSequenceX++ = fX - fWidthH;
1597 0 : *pInnerSequenceY++ = fY - fScaleY * fLarge;
1598 :
1599 0 : *pInnerSequenceX++ = fX - fScaleX * fSmall;
1600 0 : *pInnerSequenceY++ = fY;
1601 :
1602 0 : *pInnerSequenceX++ = fX - fWidthH;
1603 0 : *pInnerSequenceY++ = fY + fScaleY * fLarge;
1604 :
1605 0 : *pInnerSequenceX++ = fX - fScaleX * fLarge;
1606 0 : *pInnerSequenceY++ = fY + fHeightH;
1607 :
1608 0 : *pInnerSequenceX++ = fX;
1609 0 : *pInnerSequenceY++ = fY + fScaleY * fSmall;
1610 :
1611 0 : *pInnerSequenceX++ = fX + fScaleX * fLarge;
1612 0 : *pInnerSequenceY++ = fY + fHeightH;
1613 :
1614 0 : *pInnerSequenceX++ = fX + fWidthH;
1615 0 : *pInnerSequenceY++ = fY + fScaleY * fLarge;
1616 :
1617 0 : *pInnerSequenceX++ = fX + fScaleX * fSmall;
1618 0 : *pInnerSequenceY++ = fY;
1619 :
1620 0 : *pInnerSequenceX++ = fX + fWidthH;
1621 0 : *pInnerSequenceY++ = fY - fScaleY * fLarge;
1622 :
1623 0 : *pInnerSequenceX++ = fX + fScaleX * fLarge;
1624 0 : *pInnerSequenceY++ = fY - fHeightH;
1625 :
1626 0 : *pInnerSequenceX++ = fX;
1627 0 : *pInnerSequenceY++ = fY - fScaleY * fSmall;
1628 0 : break;
1629 :
1630 : }
1631 : case SYMBOL_PLUS:
1632 : {
1633 0 : const double fScaleX = fWidthH / 128.0;
1634 0 : const double fScaleY = fHeightH / 128.0;
1635 0 : const double fHalf = 10.0; //half line width on 256 size square
1636 0 : const double fdX = fScaleX * fHalf;
1637 0 : const double fdY = fScaleY * fHalf;
1638 :
1639 0 : *pInnerSequenceX++ = fX-fdX;
1640 0 : *pInnerSequenceY++ = fY-fHeightH;
1641 :
1642 0 : *pInnerSequenceX++ = fX-fdX;
1643 0 : *pInnerSequenceY++ = fY-fdY;
1644 :
1645 0 : *pInnerSequenceX++ = fX-fWidthH;
1646 0 : *pInnerSequenceY++ = fY-fdY;
1647 :
1648 0 : *pInnerSequenceX++ = fX-fWidthH;
1649 0 : *pInnerSequenceY++ = fY+fdY;
1650 :
1651 0 : *pInnerSequenceX++ = fX-fdX;
1652 0 : *pInnerSequenceY++ = fY+fdY;
1653 :
1654 0 : *pInnerSequenceX++ = fX-fdX;
1655 0 : *pInnerSequenceY++ = fY+fHeightH;
1656 :
1657 0 : *pInnerSequenceX++ = fX+fdX;
1658 0 : *pInnerSequenceY++ = fY+fHeightH;
1659 :
1660 0 : *pInnerSequenceX++ = fX+fdX;
1661 0 : *pInnerSequenceY++ = fY+fdY;
1662 :
1663 0 : *pInnerSequenceX++ = fX+fWidthH;
1664 0 : *pInnerSequenceY++ = fY+fdY;
1665 :
1666 0 : *pInnerSequenceX++ = fX+fWidthH;
1667 0 : *pInnerSequenceY++ = fY-fdY;
1668 :
1669 0 : *pInnerSequenceX++ = fX+fdX;
1670 0 : *pInnerSequenceY++ = fY-fdY;
1671 :
1672 0 : *pInnerSequenceX++ = fX+fdY;
1673 0 : *pInnerSequenceY++ = fY-fHeightH;
1674 :
1675 0 : *pInnerSequenceX++ = fX-fdX;
1676 0 : *pInnerSequenceY++ = fY-fHeightH;
1677 0 : break;
1678 :
1679 : }
1680 : case SYMBOL_ASTERISK:
1681 : {
1682 0 : const double fHalf = 10.0; // half line width on 256 size square
1683 0 : const double fTwoY = fHalf * sqrt(3.0);
1684 0 : const double fFourY = (128.0 - 2.0 * fHalf ) / sqrt(3.0);
1685 0 : const double fThreeX = 128.0 - fHalf;
1686 0 : const double fThreeY = fHalf * sqrt(3.0) + fFourY;
1687 0 : const double fFiveX = 2.0 * fHalf;
1688 :
1689 0 : const double fScaleX = fWidthH / 128.0;
1690 0 : const double fScaleY = fHeightH / 128.0;
1691 :
1692 : //1
1693 0 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1694 0 : *pInnerSequenceY++ = fY-fHeightH;
1695 : //2
1696 0 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1697 0 : *pInnerSequenceY++ = fY-fScaleY * fTwoY;
1698 : //3
1699 0 : *pInnerSequenceX++ = fX-fScaleX * fThreeX;
1700 0 : *pInnerSequenceY++ = fY-fScaleY * fThreeY;
1701 : //4
1702 0 : *pInnerSequenceX++ = fX-fWidthH;
1703 0 : *pInnerSequenceY++ = fY-fScaleY * fFourY;
1704 : //5
1705 0 : *pInnerSequenceX++ = fX-fScaleX * fFiveX;
1706 0 : *pInnerSequenceY++ = fY;
1707 : //6 as 4
1708 0 : *pInnerSequenceX++ = fX-fWidthH;
1709 0 : *pInnerSequenceY++ = fY+fScaleY * fFourY;
1710 : //7 as 3
1711 0 : *pInnerSequenceX++ = fX-fScaleX * fThreeX;
1712 0 : *pInnerSequenceY++ = fY+fScaleY * fThreeY;
1713 : //8 as 2
1714 0 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1715 0 : *pInnerSequenceY++ = fY+fScaleY * fTwoY;
1716 : //9 as 1
1717 0 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1718 0 : *pInnerSequenceY++ = fY+fHeightH;
1719 : //10 as 1
1720 0 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1721 0 : *pInnerSequenceY++ = fY+fHeightH;
1722 : //11 as 2
1723 0 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1724 0 : *pInnerSequenceY++ = fY+fScaleY * fTwoY;
1725 : //12 as 3
1726 0 : *pInnerSequenceX++ = fX+fScaleX * fThreeX;
1727 0 : *pInnerSequenceY++ = fY+fScaleY * fThreeY;
1728 : //13 as 4
1729 0 : *pInnerSequenceX++ = fX+fWidthH;
1730 0 : *pInnerSequenceY++ = fY+fScaleY * fFourY;
1731 : //14 as 5
1732 0 : *pInnerSequenceX++ = fX+fScaleX * fFiveX;
1733 0 : *pInnerSequenceY++ = fY;
1734 : //15 as 4
1735 0 : *pInnerSequenceX++ = fX+fWidthH;
1736 0 : *pInnerSequenceY++ = fY-fScaleY * fFourY;
1737 : //16 as 3
1738 0 : *pInnerSequenceX++ = fX+fScaleX * fThreeX;
1739 0 : *pInnerSequenceY++ = fY-fScaleY * fThreeY;
1740 : //17 as 2
1741 0 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1742 0 : *pInnerSequenceY++ = fY-fScaleY * fTwoY;
1743 : // 18 as 1
1744 0 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1745 0 : *pInnerSequenceY++ = fY-fHeightH;
1746 : // 19 = 1, closing
1747 0 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1748 0 : *pInnerSequenceY++ = fY-fHeightH;
1749 0 : break;
1750 : }
1751 : default: //case SYMBOL_SQUARE:
1752 : {
1753 0 : *pInnerSequenceX++ = fX-fWidthH;
1754 0 : *pInnerSequenceY++ = fY-fHeightH;
1755 :
1756 0 : *pInnerSequenceX++ = fX-fWidthH;
1757 0 : *pInnerSequenceY++ = fY+fHeightH;
1758 :
1759 0 : *pInnerSequenceX++ = fX+fWidthH;
1760 0 : *pInnerSequenceY++ = fY+fHeightH;
1761 :
1762 0 : *pInnerSequenceX++ = fX+fWidthH;
1763 0 : *pInnerSequenceY++ = fY-fHeightH;
1764 :
1765 0 : *pInnerSequenceX++ = fX-fWidthH;
1766 0 : *pInnerSequenceY++ = fY-fHeightH;
1767 0 : break;
1768 : }
1769 : }
1770 :
1771 0 : return aPP;
1772 : }
1773 :
1774 : uno::Reference< drawing::XShape >
1775 0 : ShapeFactory::createSymbol2D(
1776 : const uno::Reference< drawing::XShapes >& xTarget
1777 : , const drawing::Position3D& rPosition
1778 : , const drawing::Direction3D& rSize
1779 : , sal_Int32 nStandardSymbol
1780 : , sal_Int32 nBorderColor
1781 : , sal_Int32 nFillColor )
1782 : {
1783 0 : if( !xTarget.is() )
1784 0 : return 0;
1785 :
1786 : //create shape
1787 : uno::Reference< drawing::XShape > xShape(
1788 0 : m_xShapeFactory->createInstance( C2U(
1789 0 : "com.sun.star.drawing.PolyPolygonShape") ), uno::UNO_QUERY );
1790 0 : xTarget->add(xShape);
1791 :
1792 : //set properties
1793 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1794 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1795 0 : if( xProp.is())
1796 : {
1797 : try
1798 : {
1799 : drawing::PointSequenceSequence aPoints( PolyToPointSequence(
1800 0 : createPolyPolygon_Symbol( rPosition, rSize, nStandardSymbol ) ));
1801 :
1802 : //Polygon
1803 0 : xProp->setPropertyValue( C2U( UNO_NAME_POLYPOLYGON )
1804 0 : , uno::makeAny( aPoints ) );
1805 :
1806 : //LineColor
1807 0 : xProp->setPropertyValue( C2U( UNO_NAME_LINECOLOR )
1808 0 : , uno::makeAny( nBorderColor ) );
1809 :
1810 : //FillColor
1811 0 : xProp->setPropertyValue( C2U( UNO_NAME_FILLCOLOR )
1812 0 : , uno::makeAny( nFillColor ) );
1813 : }
1814 0 : catch( const uno::Exception& e )
1815 : {
1816 : ASSERT_EXCEPTION( e );
1817 : }
1818 : }
1819 0 : return xShape;
1820 : }
1821 :
1822 : uno::Reference< drawing::XShape >
1823 0 : ShapeFactory::createGraphic2D(
1824 : const uno::Reference< drawing::XShapes >& xTarget
1825 : , const drawing::Position3D& rPosition
1826 : , const drawing::Direction3D& rSize
1827 : , const uno::Reference< graphic::XGraphic >& xGraphic )
1828 : {
1829 0 : if( !xTarget.is() || !xGraphic.is() )
1830 0 : return 0;
1831 :
1832 : // @todo: change this to a rectangle shape with a fill bitmap for
1833 : // performance reasons (ask AW, said CL)
1834 :
1835 : //create shape
1836 : uno::Reference< drawing::XShape > xShape(
1837 0 : m_xShapeFactory->createInstance( C2U(
1838 0 : "com.sun.star.drawing.GraphicObjectShape") ), uno::UNO_QUERY );
1839 0 : xTarget->add(xShape);
1840 :
1841 : try
1842 : {
1843 : // assume position is upper left corner. Transform to center.
1844 : drawing::Position3D aCenterPosition(
1845 : rPosition.PositionX - (rSize.DirectionX / 2.0),
1846 : rPosition.PositionY - (rSize.DirectionY / 2.0),
1847 0 : rPosition.PositionZ );
1848 0 : xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1849 0 : xShape->setSize( Direction3DToAWTSize( rSize ));
1850 : }
1851 0 : catch( const uno::Exception & e )
1852 : {
1853 : ASSERT_EXCEPTION( e );
1854 : }
1855 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1856 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1857 0 : if( xProp.is())
1858 : {
1859 : try
1860 : {
1861 0 : xProp->setPropertyValue( C2U("Graphic"), uno::makeAny( xGraphic ));
1862 : }
1863 0 : catch( const uno::Exception& e )
1864 : {
1865 : ASSERT_EXCEPTION( e );
1866 : }
1867 : }
1868 0 : return xShape;
1869 : }
1870 :
1871 : uno::Reference< drawing::XShapes >
1872 1066 : ShapeFactory::createGroup2D( const uno::Reference< drawing::XShapes >& xTarget
1873 : , ::rtl::OUString aName )
1874 : {
1875 1066 : if( !xTarget.is() )
1876 0 : return 0;
1877 : try
1878 : {
1879 : //create and add to target
1880 : uno::Reference< drawing::XShape > xShape(
1881 1066 : m_xShapeFactory->createInstance( C2U(
1882 1066 : "com.sun.star.drawing.GroupShape" ) ), uno::UNO_QUERY );
1883 1066 : xTarget->add(xShape);
1884 :
1885 : //set name
1886 1066 : if(!aName.isEmpty())
1887 533 : setShapeName( xShape , aName );
1888 :
1889 : {//workaround
1890 : //need this null size as otherwise empty group shapes where painted with a gray border
1891 1066 : xShape->setSize(awt::Size(0,0));
1892 : }
1893 :
1894 : //return
1895 : uno::Reference< drawing::XShapes > xShapes =
1896 1066 : uno::Reference<drawing::XShapes>( xShape, uno::UNO_QUERY );
1897 1066 : return xShapes;
1898 : }
1899 0 : catch( const uno::Exception& e )
1900 : {
1901 : ASSERT_EXCEPTION( e );
1902 : }
1903 0 : return 0;
1904 : }
1905 :
1906 : uno::Reference< drawing::XShapes >
1907 0 : ShapeFactory::createGroup3D( const uno::Reference< drawing::XShapes >& xTarget
1908 : , ::rtl::OUString aName )
1909 : {
1910 0 : if( !xTarget.is() )
1911 0 : return 0;
1912 : try
1913 : {
1914 : //create shape
1915 : uno::Reference< drawing::XShape > xShape(
1916 0 : m_xShapeFactory->createInstance( C2U(
1917 0 : "com.sun.star.drawing.Shape3DSceneObject" ) ), uno::UNO_QUERY );
1918 :
1919 0 : xTarget->add(xShape);
1920 :
1921 : //it is necessary to set the transform matrix to initialize the scene properly
1922 : //otherwise all objects which are placed into this Group will not be visible
1923 : //the following should be unnecessary after a the bug is fixed
1924 : {
1925 : //set properties
1926 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1927 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1928 0 : if( xProp.is())
1929 : {
1930 : try
1931 : {
1932 0 : ::basegfx::B3DHomMatrix aM;
1933 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX )
1934 0 : , uno::makeAny(B3DHomMatrixToHomogenMatrix(aM)) );
1935 : }
1936 0 : catch( const uno::Exception& e )
1937 : {
1938 : ASSERT_EXCEPTION( e );
1939 : }
1940 0 : }
1941 : }
1942 :
1943 : //set name
1944 0 : if(!aName.isEmpty())
1945 0 : setShapeName( xShape , aName );
1946 :
1947 : //return
1948 : uno::Reference< drawing::XShapes > xShapes =
1949 0 : uno::Reference<drawing::XShapes>( xShape, uno::UNO_QUERY );
1950 0 : return xShapes;
1951 : }
1952 0 : catch( const uno::Exception& e )
1953 : {
1954 : ASSERT_EXCEPTION( e );
1955 : }
1956 0 : return 0;
1957 : }
1958 :
1959 : uno::Reference< drawing::XShape >
1960 0 : ShapeFactory::createCircle2D( const uno::Reference< drawing::XShapes >& xTarget
1961 : , const drawing::Position3D& rPosition
1962 : , const drawing::Direction3D& rSize )
1963 : {
1964 0 : if( !xTarget.is() )
1965 0 : return 0;
1966 :
1967 : //create shape
1968 : uno::Reference< drawing::XShape > xShape(
1969 0 : m_xShapeFactory->createInstance( C2U(
1970 0 : "com.sun.star.drawing.EllipseShape") ), uno::UNO_QUERY );
1971 0 : xTarget->add(xShape);
1972 :
1973 : try
1974 : {
1975 : drawing::Position3D aCenterPosition(
1976 : rPosition.PositionX - (rSize.DirectionX / 2.0),
1977 : rPosition.PositionY - (rSize.DirectionY / 2.0),
1978 0 : rPosition.PositionZ );
1979 0 : xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1980 0 : xShape->setSize( Direction3DToAWTSize( rSize ));
1981 : }
1982 0 : catch( const uno::Exception & e )
1983 : {
1984 : ASSERT_EXCEPTION( e );
1985 : }
1986 :
1987 : //set properties
1988 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1989 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1990 0 : if( xProp.is())
1991 : {
1992 : try
1993 : {
1994 0 : drawing::CircleKind eKind = drawing::CircleKind_FULL;
1995 0 : xProp->setPropertyValue( C2U( UNO_NAME_CIRCKIND )
1996 0 : , uno::makeAny( eKind ) );
1997 : }
1998 0 : catch( const uno::Exception& e )
1999 : {
2000 : ASSERT_EXCEPTION( e );
2001 : }
2002 : }
2003 0 : return xShape;
2004 : }
2005 :
2006 : uno::Reference< drawing::XShape >
2007 0 : ShapeFactory::createLine3D( const uno::Reference< drawing::XShapes >& xTarget
2008 : , const drawing::PolyPolygonShape3D& rPoints
2009 : , const VLineProperties& rLineProperties )
2010 : {
2011 0 : if( !xTarget.is() )
2012 0 : return 0;
2013 :
2014 0 : if(!rPoints.SequenceX.getLength())
2015 0 : return NULL;
2016 :
2017 : //create shape
2018 : uno::Reference< drawing::XShape > xShape(
2019 0 : m_xShapeFactory->createInstance( C2U(
2020 0 : "com.sun.star.drawing.Shape3DPolygonObject") ), uno::UNO_QUERY );
2021 0 : xTarget->add(xShape);
2022 :
2023 : //set properties
2024 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2025 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
2026 0 : if( xProp.is())
2027 : {
2028 : try
2029 : {
2030 : //Polygon
2031 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D )
2032 0 : , uno::makeAny( rPoints ) );
2033 :
2034 : //LineOnly
2035 0 : xProp->setPropertyValue( C2U( UNO_NAME_3D_LINEONLY )
2036 0 : , uno::makeAny( (sal_Bool)true ) );
2037 :
2038 : //Transparency
2039 0 : if(rLineProperties.Transparence.hasValue())
2040 0 : xProp->setPropertyValue( C2U( UNO_NAME_LINETRANSPARENCE )
2041 0 : , rLineProperties.Transparence );
2042 :
2043 : //LineStyle
2044 0 : if(rLineProperties.LineStyle.hasValue())
2045 0 : xProp->setPropertyValue( C2U( UNO_NAME_LINESTYLE )
2046 0 : , rLineProperties.LineStyle );
2047 :
2048 : //LineWidth
2049 0 : if(rLineProperties.Width.hasValue())
2050 0 : xProp->setPropertyValue( C2U( UNO_NAME_LINEWIDTH )
2051 0 : , rLineProperties.Width );
2052 :
2053 : //LineColor
2054 0 : if(rLineProperties.Color.hasValue())
2055 0 : xProp->setPropertyValue( C2U( UNO_NAME_LINECOLOR )
2056 0 : , rLineProperties.Color );
2057 : //, uno::makeAny( sal_Int32( Color(COL_RED).GetColor()) ) );
2058 : }
2059 0 : catch( const uno::Exception& e )
2060 : {
2061 : ASSERT_EXCEPTION( e );
2062 : }
2063 : }
2064 0 : return xShape;
2065 : }
2066 :
2067 : uno::Reference< drawing::XShape >
2068 246 : ShapeFactory::createLine2D( const uno::Reference< drawing::XShapes >& xTarget
2069 : , const drawing::PointSequenceSequence& rPoints
2070 : , const VLineProperties* pLineProperties )
2071 : {
2072 246 : if( !xTarget.is() )
2073 0 : return 0;
2074 :
2075 246 : if(!rPoints.getLength())
2076 0 : return NULL;
2077 :
2078 : //create shape
2079 : uno::Reference< drawing::XShape > xShape(
2080 246 : m_xShapeFactory->createInstance( C2U(
2081 246 : "com.sun.star.drawing.PolyLineShape") ), uno::UNO_QUERY );
2082 246 : xTarget->add(xShape);
2083 :
2084 : //set properties
2085 246 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2086 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
2087 246 : if( xProp.is())
2088 : {
2089 : try
2090 : {
2091 : //Polygon
2092 246 : xProp->setPropertyValue( C2U( UNO_NAME_POLYPOLYGON )
2093 246 : , uno::makeAny( rPoints ) );
2094 :
2095 246 : if(pLineProperties)
2096 : {
2097 : //Transparency
2098 246 : if(pLineProperties->Transparence.hasValue())
2099 246 : xProp->setPropertyValue( C2U( UNO_NAME_LINETRANSPARENCE )
2100 246 : , pLineProperties->Transparence );
2101 :
2102 : //LineStyle
2103 246 : if(pLineProperties->LineStyle.hasValue())
2104 246 : xProp->setPropertyValue( C2U( UNO_NAME_LINESTYLE )
2105 246 : , pLineProperties->LineStyle );
2106 :
2107 : //LineWidth
2108 246 : if(pLineProperties->Width.hasValue())
2109 246 : xProp->setPropertyValue( C2U( UNO_NAME_LINEWIDTH )
2110 246 : , pLineProperties->Width );
2111 :
2112 : //LineColor
2113 246 : if(pLineProperties->Color.hasValue())
2114 246 : xProp->setPropertyValue( C2U( UNO_NAME_LINECOLOR )
2115 246 : , pLineProperties->Color );
2116 :
2117 : //LineDashName
2118 246 : if(pLineProperties->DashName.hasValue())
2119 0 : xProp->setPropertyValue( C2U( "LineDashName" )
2120 0 : , pLineProperties->DashName );
2121 : }
2122 : }
2123 0 : catch( const uno::Exception& e )
2124 : {
2125 : ASSERT_EXCEPTION( e );
2126 : }
2127 : }
2128 246 : return xShape;
2129 : }
2130 :
2131 1230 : uno::Any ShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
2132 : {
2133 1230 : ::basegfx::B2DHomMatrix aM;
2134 : //As autogrow is active the rectangle is automatically expanded to that side
2135 : //to which the text is not adjusted.
2136 : // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
2137 1230 : aM.rotate( fRotationAnglePi );
2138 1230 : aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
2139 1230 : uno::Any aATransformation = uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) );
2140 1230 : return aATransformation;
2141 : }
2142 :
2143 205 : void ShapeFactory::makeShapeInvisible( const uno::Reference< drawing::XShape >& xShape )
2144 : {
2145 205 : uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
2146 : OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
2147 205 : if( xShapeProp.is())
2148 : {
2149 : try
2150 : {
2151 205 : xShapeProp->setPropertyValue( C2U("LineStyle"), uno::makeAny( drawing::LineStyle_NONE ));
2152 205 : xShapeProp->setPropertyValue( C2U("FillStyle"), uno::makeAny( drawing::FillStyle_NONE ));
2153 : }
2154 0 : catch( const uno::Exception& e )
2155 : {
2156 : ASSERT_EXCEPTION( e );
2157 : }
2158 205 : }
2159 205 : }
2160 :
2161 205 : uno::Reference< drawing::XShape > ShapeFactory::createInvisibleRectangle(
2162 : const uno::Reference< drawing::XShapes >& xTarget
2163 : , const awt::Size& rSize )
2164 : {
2165 : try
2166 : {
2167 205 : if(!xTarget.is())
2168 0 : return 0;
2169 :
2170 205 : uno::Reference< drawing::XShape > xShape( m_xShapeFactory->createInstance(
2171 205 : C2U( "com.sun.star.drawing.RectangleShape" )), uno::UNO_QUERY );
2172 205 : if( xTarget.is() && xShape.is())
2173 : {
2174 205 : xTarget->add( xShape );
2175 205 : ShapeFactory::makeShapeInvisible( xShape );
2176 205 : xShape->setSize( rSize );
2177 : }
2178 205 : return xShape;
2179 : }
2180 0 : catch( const uno::Exception & ex )
2181 : {
2182 : ASSERT_EXCEPTION( ex );
2183 : }
2184 0 : return 0;
2185 : }
2186 :
2187 : uno::Reference< drawing::XShape >
2188 779 : ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget
2189 : , const ::rtl::OUString& rText
2190 : , const tNameSequence& rPropNames
2191 : , const tAnySequence& rPropValues
2192 : , const uno::Any& rATransformation )
2193 : {
2194 779 : if( !xTarget.is() )
2195 0 : return 0;
2196 :
2197 779 : if(rText.isEmpty())
2198 0 : return 0;
2199 :
2200 : //create shape and add to page
2201 : uno::Reference< drawing::XShape > xShape(
2202 779 : m_xShapeFactory->createInstance( C2U(
2203 779 : "com.sun.star.drawing.TextShape" ) ), uno::UNO_QUERY );
2204 779 : xTarget->add(xShape);
2205 :
2206 : //set text
2207 779 : uno::Reference< text::XTextRange > xTextRange( xShape, uno::UNO_QUERY );
2208 779 : if( xTextRange.is() )
2209 779 : xTextRange->setString( rText );
2210 :
2211 779 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2212 779 : if( xProp.is() )
2213 : {
2214 : //set properties
2215 779 : PropertyMapper::setMultiProperties( rPropNames, rPropValues, xProp );
2216 :
2217 : //set position matrix
2218 : //the matrix needs to be set at the end behind autogrow and such position influencing properties
2219 : try
2220 : {
2221 779 : xProp->setPropertyValue( C2U( "Transformation" ), rATransformation );
2222 : }
2223 0 : catch( const uno::Exception& e )
2224 : {
2225 : ASSERT_EXCEPTION( e );
2226 : }
2227 : }
2228 779 : return xShape;
2229 : }
2230 :
2231 779 : rtl::OUString ShapeFactory::getStackedString( const rtl::OUString& rString, bool bStacked )
2232 : {
2233 779 : sal_Int32 nLen = rString.getLength();
2234 779 : if(!bStacked || !nLen)
2235 779 : return rString;
2236 :
2237 0 : rtl::OUStringBuffer aStackStr;
2238 :
2239 : //add a newline after each letter
2240 : //as we do not no letters here add a newline after each char
2241 0 : for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
2242 : {
2243 0 : if( nPosSrc )
2244 0 : aStackStr.append( sal_Unicode('\r') );
2245 0 : aStackStr.append(rString[nPosSrc]);
2246 : }
2247 0 : return aStackStr.makeStringAndClear();
2248 : }
2249 :
2250 0 : bool ShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D& rPoly)
2251 : {
2252 : // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
2253 0 : for( sal_Int32 nIdx = 0, nCount = rPoly.SequenceX.getLength(); nIdx < nCount; ++nIdx )
2254 0 : if( rPoly.SequenceX[ nIdx ].getLength() > 1 )
2255 0 : return true;
2256 0 : return false;
2257 : }
2258 :
2259 0 : bool ShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D& rPoly)
2260 : {
2261 : // true, if empty polypolygon or one polygon with one point
2262 0 : return (rPoly.SequenceX.getLength() == 0) ||
2263 0 : ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
2264 : }
2265 :
2266 0 : void ShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
2267 : {
2268 : OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "ShapeFactory::closePolygon - single polygon expected" );
2269 : //add a last point == first point
2270 0 : if(isPolygonEmptyOrSinglePoint(rPoly))
2271 0 : return;
2272 0 : drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
2273 0 : AddPointToPoly( rPoly, aFirst );
2274 : }
2275 :
2276 0 : awt::Size ShapeFactory::calculateNewSizeRespectingAspectRatio(
2277 : const awt::Size& rTargetSize
2278 : , const awt::Size& rSourceSizeWithCorrectAspectRatio )
2279 : {
2280 0 : awt::Size aNewSize;
2281 :
2282 0 : double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
2283 0 : double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
2284 0 : double fFactor = std::min(fFactorWidth,fFactorHeight);
2285 0 : aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
2286 0 : aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
2287 :
2288 0 : return aNewSize;
2289 : }
2290 :
2291 0 : awt::Point ShapeFactory::calculateTopLeftPositionToCenterObject(
2292 : const awt::Point& rTargetAreaPosition
2293 : , const awt::Size& rTargetAreaSize
2294 : , const awt::Size& rObjectSize )
2295 : {
2296 0 : awt::Point aNewPosition(rTargetAreaPosition);
2297 0 : aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
2298 0 : aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
2299 0 : return aNewPosition;
2300 : }
2301 :
2302 82 : ::basegfx::B2IRectangle ShapeFactory::getRectangleOfShape(
2303 : const uno::Reference< drawing::XShape >& xShape )
2304 : {
2305 82 : ::basegfx::B2IRectangle aRet;
2306 :
2307 82 : if( xShape.is() )
2308 : {
2309 82 : awt::Point aPos = xShape->getPosition();
2310 82 : awt::Size aSize = xShape->getSize();
2311 82 : aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
2312 : }
2313 82 : return aRet;
2314 :
2315 : }
2316 :
2317 1517 : awt::Size ShapeFactory::getSizeAfterRotation(
2318 : const uno::Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
2319 : {
2320 1517 : awt::Size aRet(0,0);
2321 1517 : if(xShape.is())
2322 : {
2323 1517 : const awt::Size aSize( xShape->getSize() );
2324 :
2325 1517 : if( ::rtl::math::approxEqual( fRotationAngleDegree, 0.0 ) )
2326 1517 : aRet = aSize;
2327 : else
2328 : {
2329 0 : while(fRotationAngleDegree>=360.0)
2330 0 : fRotationAngleDegree-=360.0;
2331 0 : while(fRotationAngleDegree<0.0)
2332 0 : fRotationAngleDegree+=360.0;
2333 0 : if(fRotationAngleDegree>270.0)
2334 0 : fRotationAngleDegree=360.0-fRotationAngleDegree;
2335 0 : else if(fRotationAngleDegree>180.0)
2336 0 : fRotationAngleDegree=fRotationAngleDegree-180.0;
2337 0 : else if(fRotationAngleDegree>90.0)
2338 0 : fRotationAngleDegree=180.0-fRotationAngleDegree;
2339 :
2340 0 : const double fAnglePi = fRotationAngleDegree*F_PI/180.0;
2341 :
2342 : aRet.Height = static_cast<sal_Int32>(
2343 0 : aSize.Width*rtl::math::sin( fAnglePi )
2344 0 : + aSize.Height*rtl::math::cos( fAnglePi ));
2345 : aRet.Width = static_cast<sal_Int32>(
2346 0 : aSize.Width*rtl::math::cos( fAnglePi )
2347 0 : + aSize.Height*rtl::math::sin( fAnglePi ));
2348 : }
2349 : }
2350 1517 : return aRet;
2351 : }
2352 :
2353 0 : void ShapeFactory::removeSubShapes( const uno::Reference< drawing::XShapes >& xShapes )
2354 : {
2355 0 : if( xShapes.is() )
2356 : {
2357 0 : sal_Int32 nSubCount = xShapes->getCount();
2358 0 : uno::Reference< drawing::XShape > xShape;
2359 0 : for( sal_Int32 nS = nSubCount; nS--; )
2360 : {
2361 0 : if( xShapes->getByIndex( nS ) >>= xShape )
2362 0 : xShapes->remove( xShape );
2363 0 : }
2364 : }
2365 0 : }
2366 :
2367 : //.............................................................................
2368 : } //namespace chart
2369 : //.............................................................................
2370 :
2371 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|