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 20496 : void ShapeFactory::setShapeName( const uno::Reference< drawing::XShape >& xShape
70 : , const OUString& rName )
71 : {
72 20496 : if(!xShape.is())
73 20496 : return;
74 20496 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
75 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
76 20496 : if( xProp.is())
77 : {
78 : try
79 : {
80 20496 : xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
81 20496 : , uno::makeAny( rName ) );
82 : }
83 0 : catch( const uno::Exception& e )
84 : {
85 : ASSERT_EXCEPTION( e );
86 : }
87 20496 : }
88 : }
89 :
90 : //-----------------------------------------------------------------------------
91 :
92 1479 : OUString ShapeFactory::getShapeName( const uno::Reference< drawing::XShape >& xShape )
93 : {
94 1479 : OUString aRet;
95 :
96 2958 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
97 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
98 1479 : if( xProp.is())
99 : {
100 : try
101 : {
102 1479 : xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
103 : }
104 0 : catch( const uno::Exception& e )
105 : {
106 : ASSERT_EXCEPTION( e );
107 : }
108 : }
109 :
110 2958 : return aRet;
111 : }
112 :
113 : //-----------------------------------------------------------------------------
114 :
115 1568 : uno::Reference< drawing::XShapes > ShapeFactory::getChartRootShape(
116 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
117 : {
118 1568 : uno::Reference< drawing::XShapes > xRet;
119 3136 : uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
120 1568 : if( xShapes.is() )
121 : {
122 1568 : sal_Int32 nCount = xShapes->getCount();
123 1568 : uno::Reference< drawing::XShape > xShape;
124 3136 : for( sal_Int32 nN = nCount; nN--; )
125 : {
126 1479 : if( xShapes->getByIndex( nN ) >>= xShape )
127 : {
128 1479 : if( ShapeFactory::getShapeName( xShape ).equals("com.sun.star.chart2.shapes") )
129 : {
130 1479 : xRet = uno::Reference< drawing::XShapes >( xShape, uno::UNO_QUERY );
131 1479 : break;
132 : }
133 : }
134 1568 : }
135 : }
136 3136 : return xRet;
137 : }
138 :
139 : //-----------------------------------------------------------------------------
140 :
141 919 : uno::Reference< drawing::XShapes > ShapeFactory::getOrCreateChartRootShape(
142 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
143 : {
144 919 : uno::Reference< drawing::XShapes > xRet( ShapeFactory::getChartRootShape( xDrawPage ) );
145 919 : if( !xRet.is() )
146 : {
147 : //create the root shape
148 178 : xRet = this->createGroup2D(
149 : uno::Reference<drawing::XShapes>( xDrawPage, uno::UNO_QUERY )
150 89 : , "com.sun.star.chart2.shapes" );
151 : }
152 919 : return xRet;
153 : }
154 :
155 : //-----------------------------------------------------------------------------
156 : //-----------------------------------------------------------------------------
157 : // diverse PolyPolygon create methods
158 : //-----------------------------------------------------------------------------
159 : //-----------------------------------------------------------------------------
160 :
161 842 : 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 842 : if( fRoundedEdge == 0.0 && bRounded)
168 0 : fRoundedEdge = 0.4 / 200.0;
169 842 : else if(!bRounded)
170 842 : fRoundedEdge = 0.0;
171 :
172 : //fWidthH stands for Half Width
173 842 : const double fWidthH = rSize.DirectionX >=0.0? rSize.DirectionX/2.0 : -rSize.DirectionX/2.0;
174 842 : const double fHeight = rSize.DirectionY;
175 :
176 842 : const double fHeightSign = fHeight >= 0.0 ? 1.0 : -1.0;
177 :
178 842 : const double fOffset = (fWidthH * fRoundedEdge) * 1.05; // increase by 5% for safety
179 842 : const bool bRoundEdges = fRoundedEdge && fOffset < fWidthH && 2.0 * fOffset < fHeightSign*fHeight;
180 842 : const sal_Int32 nPointCount = bRoundEdges ? 13 : 5;
181 :
182 : //--------------------------------------
183 842 : drawing::PolyPolygonShape3D aPP;
184 :
185 842 : aPP.SequenceX.realloc(1);
186 842 : aPP.SequenceY.realloc(1);
187 842 : aPP.SequenceZ.realloc(1);
188 :
189 842 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
190 842 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
191 842 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
192 :
193 842 : pOuterSequenceX->realloc(nPointCount);
194 842 : pOuterSequenceY->realloc(nPointCount);
195 842 : pOuterSequenceZ->realloc(nPointCount);
196 :
197 842 : double* pInnerSequenceX = pOuterSequenceX->getArray();
198 842 : double* pInnerSequenceY = pOuterSequenceY->getArray();
199 842 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
200 :
201 5894 : for(sal_Int32 nN = nPointCount; nN--;)
202 4210 : *pInnerSequenceZ++ = 0.0;
203 :
204 842 : if(nPointCount == 5)
205 : {
206 842 : *pInnerSequenceY++ = 0.0;
207 842 : *pInnerSequenceY++ = 0.0;
208 842 : *pInnerSequenceY++ = fHeight;
209 842 : *pInnerSequenceY++ = fHeight;
210 842 : *pInnerSequenceY++ = 0.0;
211 :
212 842 : *pInnerSequenceX++ = -fWidthH;
213 842 : *pInnerSequenceX++ = fWidthH;
214 842 : *pInnerSequenceX++ = fWidthH;
215 842 : *pInnerSequenceX++ = -fWidthH;
216 842 : *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 842 : 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 842 : 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 842 : if( !xTarget.is() )
437 0 : return 0;
438 842 : if( bRounded )
439 : {
440 : try
441 : {
442 0 : if( xSourceProp.is() )
443 : {
444 : drawing::LineStyle aLineStyle;
445 0 : xSourceProp->getPropertyValue( "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 842 : uno::Reference<drawing::XShape> xShape = impl_createCube( xTarget, rPosition, rSize, nRotateZAngleHundredthDegree, bRounded );
456 1684 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
457 842 : if( xSourceProp.is())
458 24 : PropertyMapper::setMappedProperties( xProp, xSourceProp, rPropertyNameMap );
459 1684 : return xShape;
460 : }
461 :
462 : uno::Reference<drawing::XShape>
463 842 : 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 842 : if( !xTarget.is() )
470 0 : return 0;
471 :
472 : //create shape
473 : uno::Reference< drawing::XShape > xShape(
474 842 : m_xShapeFactory->createInstance(
475 842 : "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY );
476 842 : xTarget->add(xShape);
477 :
478 : //set properties
479 1684 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
480 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
481 842 : if( xProp.is())
482 : {
483 : try
484 : {
485 : //depth
486 842 : double fDepth = rSize.DirectionZ;
487 842 : if(fDepth<0)
488 0 : fDepth*=-1.0;
489 842 : xProp->setPropertyValue( UNO_NAME_3D_EXTRUDE_DEPTH
490 842 : , uno::makeAny((sal_Int32)fDepth) );
491 :
492 : //PercentDiagonal
493 842 : sal_Int16 nPercentDiagonal = bRounded ? 3 : 0;
494 842 : xProp->setPropertyValue( UNO_NAME_3D_PERCENT_DIAGONAL
495 842 : , uno::makeAny( nPercentDiagonal ) );
496 :
497 : //Polygon
498 842 : xProp->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
499 842 : , createPolyPolygon_Cube( rSize, double(nPercentDiagonal)/200.0,bRounded) );
500 :
501 : //Matrix for position
502 : {
503 842 : ::basegfx::B3DHomMatrix aM;
504 842 : 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 842 : , rPosition.PositionZ - (fDepth/2.0));
509 842 : drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
510 842 : xProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
511 842 : , uno::makeAny(aHM) );
512 : }
513 : }
514 0 : catch( const uno::Exception& e )
515 : {
516 : ASSERT_EXCEPTION( e );
517 : }
518 : }
519 1684 : 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, 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(
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( 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( 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( UNO_NAME_3D_TRANSFORM_MATRIX
751 0 : , uno::makeAny(aHM) );
752 : }
753 :
754 : //Segments
755 0 : xProp->setPropertyValue( UNO_NAME_3D_HORZ_SEGS
756 0 : , uno::makeAny(CHART_3DOBJECT_SEGMENTCOUNT) );
757 0 : xProp->setPropertyValue( 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( 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 104 : void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords& rReturn, const drawing::PolyPolygonBezierCoords& rAdd, sal_Bool bAppendInverse )
777 : {
778 104 : if(!rAdd.Coordinates.getLength())
779 0 : return;
780 104 : sal_Int32 nAddCount = rAdd.Coordinates[0].getLength();
781 104 : if(!nAddCount)
782 0 : return;
783 :
784 104 : sal_Int32 nOldCount = rReturn.Coordinates[0].getLength();
785 :
786 104 : rReturn.Coordinates[0].realloc(nOldCount+nAddCount+1);
787 104 : rReturn.Flags[0].realloc(nOldCount+nAddCount+1);
788 :
789 2080 : for(sal_Int32 nN=0;nN<nAddCount; nN++ )
790 : {
791 1976 : sal_Int32 nAdd = bAppendInverse ? (nAddCount-1-nN) : nN;
792 1976 : rReturn.Coordinates[0][nOldCount+nN] = rAdd.Coordinates[0][nAdd];
793 1976 : rReturn.Flags[0][nOldCount+nN] = rAdd.Flags[0][nAdd];
794 : }
795 :
796 : //close
797 104 : rReturn.Coordinates[0][nOldCount+nAddCount] = rReturn.Coordinates[0][0];
798 104 : rReturn.Flags[0][nOldCount+nAddCount] = rReturn.Flags[0][0];
799 : }
800 :
801 : //------------------------------------------------------------------------------------------------------------
802 :
803 208 : 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 208 : drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
812 208 : sal_Int32 nSegmentCount = static_cast< sal_Int32 >( fWidthAngleRadian/fAngleSubdivisionRadian );
813 208 : if( fWidthAngleRadian > fAngleSubdivisionRadian*nSegmentCount )
814 208 : nSegmentCount++;
815 :
816 208 : double fFirstSegmentAngle = fAngleSubdivisionRadian;
817 208 : double fLastSegmentAngle = fAngleSubdivisionRadian;
818 208 : if(nSegmentCount==1)
819 : {
820 0 : fFirstSegmentAngle = fWidthAngleRadian;
821 0 : fLastSegmentAngle = 0.0;
822 : }
823 : else
824 : {
825 208 : double fFirstAngleOnSubDevision = (static_cast<sal_Int32>(fStartAngleRadian/fAngleSubdivisionRadian)+1)*fAngleSubdivisionRadian;
826 208 : if( !::rtl::math::approxEqual( fStartAngleRadian, fFirstAngleOnSubDevision ) )
827 208 : fFirstSegmentAngle = fFirstAngleOnSubDevision-fStartAngleRadian;
828 :
829 208 : if(nSegmentCount>1)
830 : {
831 208 : fLastSegmentAngle = fWidthAngleRadian-fFirstSegmentAngle-fAngleSubdivisionRadian*(nSegmentCount-2);
832 208 : if( fLastSegmentAngle<0 )
833 0 : nSegmentCount--;
834 208 : if( fLastSegmentAngle>fAngleSubdivisionRadian )
835 : {
836 104 : fLastSegmentAngle-=fAngleSubdivisionRadian;
837 104 : nSegmentCount++;
838 : }
839 : }
840 : }
841 :
842 208 : sal_Int32 nPointCount = 1 + 3*nSegmentCount; //first point of next segment equals last point of former segment
843 :
844 208 : aReturn.Coordinates = drawing::PointSequenceSequence(1);
845 208 : aReturn.Flags = drawing::FlagSequenceSequence(1);
846 :
847 416 : drawing::PointSequence aPoints(nPointCount);
848 416 : 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 416 : ::basegfx::B2DPoint P0,P1,P2,P3;
854 :
855 208 : sal_Int32 nPoint=0;
856 208 : double fCurrentRotateAngle = fStartAngleRadian;
857 1456 : for(sal_Int32 nSegment=0; nSegment<nSegmentCount; nSegment++)
858 : {
859 1248 : double fCurrentSegmentAngle = fAngleSubdivisionRadian;
860 1248 : if(nSegment==0)//first segment gets only a smaller peace until the next subdevision
861 208 : fCurrentSegmentAngle = fFirstSegmentAngle;
862 1040 : else if(nSegment==(nSegmentCount-1)) //the last segment gets the rest angle that does not fit into equal pieces
863 208 : fCurrentSegmentAngle = fLastSegmentAngle;
864 :
865 : //first create untransformed points for a unit circle arc:
866 1248 : const double fCos = cos(fCurrentSegmentAngle/2.0);
867 1248 : const double fSin = sin(fCurrentSegmentAngle/2.0);
868 1248 : P0.setX(fCos);
869 1248 : P3.setX(fCos);
870 1248 : P0.setY(-fSin);
871 1248 : P3.setY(-P0.getY());
872 :
873 1248 : P1.setX((4.0-fCos)/3.0);
874 1248 : P2.setX(P1.getX());
875 1248 : P1.setY((1.0-fCos)*(fCos-3.0)/(3.0*fSin));
876 1248 : P2.setY(-P1.getY());
877 : //transform thus startangle equals NULL
878 1248 : ::basegfx::B2DHomMatrix aStart;
879 1248 : aStart.rotate(fCurrentSegmentAngle/2.0 + fCurrentRotateAngle );
880 1248 : fCurrentRotateAngle+=fCurrentSegmentAngle;
881 :
882 1248 : aStart.scale( fUnitRadius, fUnitRadius );
883 :
884 : //apply given transformation to get final points
885 1248 : P0 = rTransformationFromUnitCircle*(aStart*P0);
886 1248 : P1 = rTransformationFromUnitCircle*(aStart*P1);
887 1248 : P2 = rTransformationFromUnitCircle*(aStart*P2);
888 1248 : P3 = rTransformationFromUnitCircle*(aStart*P3);
889 :
890 1248 : aPoints[nPoint].X = static_cast< sal_Int32 >( P0.getX());
891 1248 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P0.getY());
892 1248 : aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
893 :
894 1248 : aPoints[nPoint].X = static_cast< sal_Int32 >( P1.getX());
895 1248 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P1.getY());
896 1248 : aFlags[nPoint++] = drawing::PolygonFlags_CONTROL;
897 :
898 1248 : aPoints[nPoint].X = static_cast< sal_Int32 >( P2.getX());
899 1248 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P2.getY());
900 1248 : aFlags [nPoint++] = drawing::PolygonFlags_CONTROL;
901 :
902 1248 : if(nSegment==(nSegmentCount-1))
903 : {
904 208 : aPoints[nPoint].X = static_cast< sal_Int32 >( P3.getX());
905 208 : aPoints[nPoint].Y = static_cast< sal_Int32 >( P3.getY());
906 208 : aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
907 : }
908 1248 : }
909 :
910 208 : aReturn.Coordinates[0] = aPoints;
911 208 : aReturn.Flags[0] = aFlags;
912 :
913 416 : return aReturn;
914 : }
915 :
916 : //------------------------------------------------------------------------------------------------------------
917 :
918 104 : drawing::PolyPolygonBezierCoords getRingBezierCoords(
919 : double fUnitCircleInnerRadius
920 : , double fUnitCircleOuterRadius
921 : , double fStartAngleRadian, double fWidthAngleRadian
922 : , ::basegfx::B2DHomMatrix aTransformationFromUnitCircle
923 : , const double fAngleSubdivisionRadian )
924 : {
925 104 : drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
926 :
927 104 : aReturn.Coordinates = drawing::PointSequenceSequence(1);
928 104 : aReturn.Flags = drawing::FlagSequenceSequence(1);
929 :
930 : drawing::PolyPolygonBezierCoords aOuterArc = getCircularArcBezierCoords(
931 208 : fStartAngleRadian, fWidthAngleRadian, fUnitCircleOuterRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
932 104 : aReturn.Coordinates[0] = aOuterArc.Coordinates[0];
933 104 : aReturn.Flags[0] = aOuterArc.Flags[0];
934 :
935 : drawing::PolyPolygonBezierCoords aInnerArc = getCircularArcBezierCoords(
936 208 : fStartAngleRadian, fWidthAngleRadian, fUnitCircleInnerRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
937 104 : appendAndCloseBezierCoords( aReturn, aInnerArc, sal_True );
938 :
939 208 : return aReturn;
940 : }
941 :
942 : //------------------------------------------------------------------------------------------------------------
943 :
944 : uno::Reference< drawing::XShape >
945 104 : ShapeFactory::createPieSegment2D(
946 : const uno::Reference< drawing::XShapes >& xTarget
947 : , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
948 : , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
949 : , const drawing::Direction3D& rOffset
950 : , const drawing::HomogenMatrix& rUnitCircleToScene )
951 : {
952 104 : if( !xTarget.is() )
953 0 : return 0;
954 :
955 208 : while(fUnitCircleWidthAngleDegree>360)
956 0 : fUnitCircleWidthAngleDegree -= 360.0;
957 208 : while(fUnitCircleWidthAngleDegree<0)
958 0 : fUnitCircleWidthAngleDegree += 360.0;
959 :
960 : //create shape
961 : uno::Reference< drawing::XShape > xShape(
962 104 : m_xShapeFactory->createInstance(
963 104 : "com.sun.star.drawing.ClosedBezierShape" ), uno::UNO_QUERY );
964 104 : xTarget->add(xShape); //need to add the shape before setting of properties
965 :
966 : //set properties
967 208 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
968 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
969 104 : if( xProp.is())
970 : {
971 : try
972 : {
973 104 : ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
974 104 : aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
975 :
976 104 : const double fAngleSubdivisionRadian = F_PI/10.0;
977 :
978 : drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
979 : fUnitCircleInnerRadius, fUnitCircleOuterRadius
980 208 : , fUnitCircleStartAngleDegree*F_PI/180.0, fUnitCircleWidthAngleDegree*F_PI/180.0
981 416 : , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
982 :
983 208 : xProp->setPropertyValue( "PolyPolygonBezier", uno::makeAny( aCoords ) );
984 : }
985 0 : catch( const uno::Exception& e )
986 : {
987 : ASSERT_EXCEPTION( e );
988 : }
989 : }
990 :
991 208 : return xShape;
992 : }
993 :
994 : //------------------------------------------------------------------------------------------------------------
995 :
996 : uno::Reference< drawing::XShape >
997 0 : ShapeFactory::createPieSegment(
998 : const uno::Reference< drawing::XShapes >& xTarget
999 : , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
1000 : , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
1001 : , const drawing::Direction3D& rOffset
1002 : , const drawing::HomogenMatrix& rUnitCircleToScene
1003 : , double fDepth )
1004 : {
1005 0 : if( !xTarget.is() )
1006 0 : return 0;
1007 :
1008 0 : while(fUnitCircleWidthAngleDegree>360)
1009 0 : fUnitCircleWidthAngleDegree -= 360.0;
1010 0 : while(fUnitCircleWidthAngleDegree<0)
1011 0 : fUnitCircleWidthAngleDegree += 360.0;
1012 :
1013 : //create shape
1014 : uno::Reference< drawing::XShape > xShape(
1015 0 : m_xShapeFactory->createInstance(
1016 0 : "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY );
1017 0 : xTarget->add(xShape); //need to add the shape before setting of properties
1018 :
1019 : //set properties
1020 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1021 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1022 0 : if( xProp.is())
1023 : {
1024 : try
1025 : {
1026 0 : ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(rUnitCircleToScene) ) );
1027 0 : aTransformationFromUnitCircle.translate(rOffset.DirectionX,rOffset.DirectionY);
1028 :
1029 0 : const double fAngleSubdivisionRadian = F_PI/32.0;
1030 :
1031 : drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
1032 : fUnitCircleInnerRadius, fUnitCircleOuterRadius
1033 0 : , fUnitCircleStartAngleDegree*F_PI/180.0, fUnitCircleWidthAngleDegree*F_PI/180.0
1034 0 : , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
1035 :
1036 : //depth
1037 0 : xProp->setPropertyValue( UNO_NAME_3D_EXTRUDE_DEPTH
1038 0 : , uno::makeAny((sal_Int32)fDepth) );
1039 :
1040 : //PercentDiagonal
1041 0 : sal_Int16 nPercentDiagonal = 0;
1042 0 : xProp->setPropertyValue( UNO_NAME_3D_PERCENT_DIAGONAL
1043 0 : , uno::makeAny( nPercentDiagonal ) );
1044 :
1045 : //Polygon
1046 0 : drawing::PolyPolygonShape3D aPoly( BezierToPoly(aCoords) );
1047 0 : ShapeFactory::closePolygon( aPoly );
1048 0 : xProp->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
1049 0 : , uno::makeAny( aPoly ) );
1050 :
1051 : //DoubleSided
1052 0 : xProp->setPropertyValue( UNO_NAME_3D_DOUBLE_SIDED
1053 0 : , uno::makeAny( (sal_Bool)true) );
1054 :
1055 : //Reduced lines
1056 0 : xProp->setPropertyValue( UNO_NAME_3D_REDUCED_LINE_GEOMETRY
1057 0 : , uno::makeAny((sal_Bool)sal_True) );
1058 :
1059 : //TextureProjectionMode
1060 0 : xProp->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
1061 0 : , uno::makeAny( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
1062 :
1063 : //TextureProjectionMode
1064 0 : xProp->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_X
1065 0 : , uno::makeAny( drawing::TextureProjectionMode_PARALLEL ) );
1066 0 : xProp->setPropertyValue( UNO_NAME_3D_TEXTURE_PROJ_Y
1067 0 : , uno::makeAny( drawing::TextureProjectionMode_OBJECTSPECIFIC ) );
1068 : }
1069 0 : catch( const uno::Exception& e )
1070 : {
1071 : ASSERT_EXCEPTION( e );
1072 : }
1073 : }
1074 0 : return xShape;
1075 : }
1076 :
1077 : //------------------------------------------------------------------------------------------------------------
1078 : //------------------------------------------------------------------------------------------------------------
1079 : //------------------------------------------------------------------------------------------------------------
1080 :
1081 : uno::Reference< drawing::XShape >
1082 240 : ShapeFactory::createStripe( const uno::Reference< drawing::XShapes >& xTarget
1083 : , const Stripe& rStripe
1084 : , const uno::Reference< beans::XPropertySet >& xSourceProp
1085 : , const tPropertyNameMap& rPropertyNameMap
1086 : , sal_Bool bDoubleSided
1087 : , short nRotatedTexture
1088 : , bool bFlatNormals )
1089 : {
1090 240 : if( !xTarget.is() )
1091 0 : return 0;
1092 :
1093 : //create shape
1094 : uno::Reference< drawing::XShape > xShape(
1095 240 : m_xShapeFactory->createInstance(
1096 240 : "com.sun.star.drawing.Shape3DPolygonObject" ), uno::UNO_QUERY );
1097 240 : xTarget->add(xShape);
1098 :
1099 : //set properties
1100 480 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1101 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1102 240 : if( xProp.is())
1103 : {
1104 : try
1105 : {
1106 : //Polygon
1107 240 : xProp->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
1108 240 : , rStripe.getPolyPolygonShape3D() );
1109 :
1110 : //TexturePolygon
1111 240 : xProp->setPropertyValue( UNO_NAME_3D_TEXTUREPOLYGON3D
1112 240 : , rStripe.getTexturePolygon( nRotatedTexture ) );
1113 :
1114 : //Normals Polygon
1115 240 : xProp->setPropertyValue( UNO_NAME_3D_NORMALSPOLYGON3D
1116 240 : , rStripe.getNormalsPolygon() );
1117 : //NormalsKind
1118 240 : if(bFlatNormals)
1119 240 : xProp->setPropertyValue( UNO_NAME_3D_NORMALS_KIND
1120 240 : , uno::makeAny( drawing::NormalsKind_FLAT ) );
1121 :
1122 : //LineOnly
1123 240 : xProp->setPropertyValue( UNO_NAME_3D_LINEONLY
1124 240 : , uno::makeAny( (sal_Bool)false) );
1125 :
1126 : //DoubleSided
1127 240 : xProp->setPropertyValue( UNO_NAME_3D_DOUBLE_SIDED
1128 240 : , uno::makeAny(bDoubleSided) );
1129 :
1130 240 : if( xSourceProp.is())
1131 240 : PropertyMapper::setMappedProperties( xProp, xSourceProp, rPropertyNameMap );
1132 : }
1133 0 : catch( const uno::Exception& e )
1134 : {
1135 : ASSERT_EXCEPTION( e );
1136 : }
1137 : }
1138 480 : return xShape;
1139 : }
1140 :
1141 : uno::Reference< drawing::XShape >
1142 0 : ShapeFactory::createArea3D( const uno::Reference< drawing::XShapes >& xTarget
1143 : , const drawing::PolyPolygonShape3D& rPolyPolygon
1144 : , double fDepth )
1145 : {
1146 0 : if( !xTarget.is() )
1147 0 : return 0;
1148 :
1149 0 : if( !rPolyPolygon.SequenceX.getLength())
1150 0 : return 0;
1151 :
1152 : //create shape
1153 : uno::Reference< drawing::XShape > xShape(
1154 0 : m_xShapeFactory->createInstance(
1155 0 : "com.sun.star.drawing.Shape3DExtrudeObject" ), uno::UNO_QUERY );
1156 0 : xTarget->add(xShape);
1157 :
1158 : //set properties
1159 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1160 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1161 0 : if( xProp.is())
1162 : {
1163 : try
1164 : {
1165 : //depth
1166 0 : xProp->setPropertyValue( UNO_NAME_3D_EXTRUDE_DEPTH
1167 0 : , uno::makeAny((sal_Int32)fDepth) );
1168 :
1169 : //PercentDiagonal
1170 0 : sal_Int16 nPercentDiagonal = 0;
1171 0 : xProp->setPropertyValue( UNO_NAME_3D_PERCENT_DIAGONAL
1172 0 : , uno::makeAny( nPercentDiagonal ) );
1173 :
1174 : //Polygon
1175 0 : xProp->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
1176 0 : , uno::makeAny( rPolyPolygon ) );
1177 :
1178 : //DoubleSided
1179 0 : xProp->setPropertyValue( UNO_NAME_3D_DOUBLE_SIDED
1180 0 : , uno::makeAny( (sal_Bool)true) );
1181 :
1182 : //the z component of the polygon is now ignored by the drawing layer,
1183 : //so we nned to translate the object via transformation matrix
1184 :
1185 : //Matrix for position
1186 0 : if( rPolyPolygon.SequenceZ.getLength()&& rPolyPolygon.SequenceZ[0].getLength() )
1187 : {
1188 0 : ::basegfx::B3DHomMatrix aM;
1189 : aM.translate( 0
1190 : , 0
1191 0 : , rPolyPolygon.SequenceZ[0][0] );
1192 0 : drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM);
1193 0 : xProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
1194 0 : , uno::makeAny(aHM) );
1195 : }
1196 : }
1197 0 : catch( const uno::Exception& e )
1198 : {
1199 : ASSERT_EXCEPTION( e );
1200 : }
1201 : }
1202 0 : return xShape;
1203 : }
1204 :
1205 : uno::Reference< drawing::XShape >
1206 5974 : ShapeFactory::createArea2D( const uno::Reference< drawing::XShapes >& xTarget
1207 : , const drawing::PolyPolygonShape3D& rPolyPolygon )
1208 : {
1209 5974 : if( !xTarget.is() )
1210 0 : return 0;
1211 :
1212 : //create shape
1213 : uno::Reference< drawing::XShape > xShape(
1214 5974 : m_xShapeFactory->createInstance(
1215 5974 : "com.sun.star.drawing.PolyPolygonShape" ), uno::UNO_QUERY );
1216 5974 : xTarget->add(xShape);
1217 :
1218 : //set properties
1219 11948 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1220 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1221 5974 : if( xProp.is())
1222 : {
1223 : try
1224 : {
1225 : //UNO_NAME_POLYGON "Polygon" drawing::PointSequence*
1226 5974 : drawing::PointSequenceSequence aPoints( PolyToPointSequence(rPolyPolygon) );
1227 :
1228 : //Polygon
1229 5974 : xProp->setPropertyValue( UNO_NAME_POLYPOLYGON
1230 5974 : , uno::makeAny( aPoints ) );
1231 :
1232 : //ZOrder
1233 : //an area should always be behind other shapes
1234 5974 : xProp->setPropertyValue( UNO_NAME_MISC_OBJ_ZORDER
1235 5974 : , uno::makeAny( sal_Int32(0) ) );
1236 : }
1237 0 : catch( const uno::Exception& e )
1238 : {
1239 : ASSERT_EXCEPTION( e );
1240 : }
1241 : }
1242 11948 : return xShape;
1243 : }
1244 :
1245 : // Be careful here not to clash with the SYMBOL_FOO #defines in
1246 : // <rsc/rsc-vcl-shared-types.hxx>
1247 :
1248 : enum SymbolEnum { Symbol_Square=0
1249 : , Symbol_Diamond
1250 : , Symbol_DownArrow
1251 : , Symbol_UpArrow
1252 : , Symbol_RightArrow
1253 : , Symbol_LeftArrow
1254 : , Symbol_Bowtie
1255 : , Symbol_Sandglass
1256 : , Symbol_Circle
1257 : , Symbol_Star
1258 : , Symbol_X
1259 : , Symbol_Plus
1260 : , Symbol_Asterisk
1261 : , Symbol_HorizontalBar
1262 : , Symbol_VerticalBar
1263 : , Symbol_COUNT
1264 : };
1265 :
1266 109 : sal_Int32 ShapeFactory::getSymbolCount()
1267 : {
1268 109 : return Symbol_COUNT;
1269 : }
1270 :
1271 109 : drawing::PolyPolygonShape3D createPolyPolygon_Symbol( const drawing::Position3D& rPos
1272 : , const drawing::Direction3D& rSize
1273 : , sal_Int32 nStandardSymbol )
1274 : {
1275 109 : if(nStandardSymbol<0)
1276 0 : nStandardSymbol*=-1;
1277 109 : nStandardSymbol = nStandardSymbol%ShapeFactory::getSymbolCount();
1278 109 : SymbolEnum eSymbolType=static_cast<SymbolEnum>(nStandardSymbol);
1279 :
1280 109 : const double& fX = rPos.PositionX;
1281 109 : const double& fY = rPos.PositionY;
1282 :
1283 109 : const double fWidthH = rSize.DirectionX/2.0; //fWidthH stands for Half Width
1284 109 : const double fHeightH = rSize.DirectionY/2.0; //fHeightH stands for Half Height
1285 :
1286 109 : const sal_Int32 nQuarterCount = 35; // points inside a quadrant, used in case circle
1287 :
1288 109 : sal_Int32 nPointCount = 4; //all arrow symbols only need 4 points
1289 109 : switch( eSymbolType )
1290 : {
1291 : case Symbol_Square:
1292 : case Symbol_Diamond:
1293 : case Symbol_Bowtie:
1294 : case Symbol_Sandglass:
1295 : case Symbol_HorizontalBar:
1296 : case Symbol_VerticalBar:
1297 68 : nPointCount = 5;
1298 68 : break;
1299 : case Symbol_X:
1300 4 : nPointCount = 13;
1301 4 : break;
1302 : case Symbol_Plus:
1303 4 : nPointCount = 13;
1304 4 : break;
1305 : case Symbol_Star:
1306 4 : nPointCount = 9;
1307 4 : break;
1308 : case Symbol_Asterisk:
1309 4 : nPointCount = 19;
1310 4 : break;
1311 : case Symbol_Circle:
1312 4 : nPointCount = 5 + 4 * nQuarterCount;
1313 4 : break;
1314 : default:
1315 21 : break;
1316 : }
1317 :
1318 : //--------------------------------------
1319 109 : drawing::PolyPolygonShape3D aPP;
1320 :
1321 109 : aPP.SequenceX.realloc(1);
1322 109 : aPP.SequenceY.realloc(1);
1323 109 : aPP.SequenceZ.realloc(1);
1324 :
1325 109 : drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray();
1326 109 : drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray();
1327 109 : drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray();
1328 :
1329 109 : pOuterSequenceX->realloc(nPointCount);
1330 109 : pOuterSequenceY->realloc(nPointCount);
1331 109 : pOuterSequenceZ->realloc(nPointCount);
1332 :
1333 109 : double* pInnerSequenceX = pOuterSequenceX->getArray();
1334 109 : double* pInnerSequenceY = pOuterSequenceY->getArray();
1335 109 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
1336 :
1337 1438 : for(sal_Int32 nN = nPointCount; nN--;)
1338 1220 : *pInnerSequenceZ++ = 0.0;
1339 :
1340 109 : switch(eSymbolType)
1341 : {
1342 : case Symbol_Square:
1343 : {
1344 42 : *pInnerSequenceX++ = fX-fWidthH;
1345 42 : *pInnerSequenceY++ = fY-fHeightH;
1346 :
1347 42 : *pInnerSequenceX++ = fX-fWidthH;
1348 42 : *pInnerSequenceY++ = fY+fHeightH;
1349 :
1350 42 : *pInnerSequenceX++ = fX+fWidthH;
1351 42 : *pInnerSequenceY++ = fY+fHeightH;
1352 :
1353 42 : *pInnerSequenceX++ = fX+fWidthH;
1354 42 : *pInnerSequenceY++ = fY-fHeightH;
1355 :
1356 42 : *pInnerSequenceX++ = fX-fWidthH;
1357 42 : *pInnerSequenceY++ = fY-fHeightH;
1358 42 : break;
1359 : }
1360 : case Symbol_UpArrow:
1361 : {
1362 4 : *pInnerSequenceX++ = fX-fWidthH;
1363 4 : *pInnerSequenceY++ = fY+fHeightH;
1364 :
1365 4 : *pInnerSequenceX++ = fX+fWidthH;
1366 4 : *pInnerSequenceY++ = fY+fHeightH;
1367 :
1368 4 : *pInnerSequenceX++ = fX;
1369 4 : *pInnerSequenceY++ = fY-fHeightH;
1370 :
1371 4 : *pInnerSequenceX++ = fX-fWidthH;
1372 4 : *pInnerSequenceY++ = fY+fHeightH;
1373 4 : break;
1374 : }
1375 : case Symbol_DownArrow:
1376 : {
1377 9 : *pInnerSequenceX++ = fX-fWidthH;
1378 9 : *pInnerSequenceY++ = fY-fHeightH;
1379 :
1380 9 : *pInnerSequenceX++ = fX;
1381 9 : *pInnerSequenceY++ = fY+fHeightH;
1382 :
1383 9 : *pInnerSequenceX++ = fX+fWidthH;
1384 9 : *pInnerSequenceY++ = fY-fHeightH;
1385 :
1386 9 : *pInnerSequenceX++ = fX-fWidthH;
1387 9 : *pInnerSequenceY++ = fY-fHeightH;
1388 9 : break;
1389 : }
1390 : case Symbol_RightArrow:
1391 : {
1392 4 : *pInnerSequenceX++ = fX-fWidthH;
1393 4 : *pInnerSequenceY++ = fY-fHeightH;
1394 :
1395 4 : *pInnerSequenceX++ = fX-fWidthH;
1396 4 : *pInnerSequenceY++ = fY+fHeightH;
1397 :
1398 4 : *pInnerSequenceX++ = fX+fWidthH;
1399 4 : *pInnerSequenceY++ = fY;
1400 :
1401 4 : *pInnerSequenceX++ = fX-fWidthH;
1402 4 : *pInnerSequenceY++ = fY-fHeightH;
1403 4 : break;
1404 : }
1405 : case Symbol_LeftArrow:
1406 : {
1407 4 : *pInnerSequenceX++ = fX-fWidthH;
1408 4 : *pInnerSequenceY++ = fY;
1409 :
1410 4 : *pInnerSequenceX++ = fX+fWidthH;
1411 4 : *pInnerSequenceY++ = fY+fHeightH;
1412 :
1413 4 : *pInnerSequenceX++ = fX+fWidthH;
1414 4 : *pInnerSequenceY++ = fY-fHeightH;
1415 :
1416 4 : *pInnerSequenceX++ = fX-fWidthH;
1417 4 : *pInnerSequenceY++ = fY;
1418 4 : break;
1419 : }
1420 : case Symbol_Bowtie:
1421 : {
1422 4 : *pInnerSequenceX++ = fX-fWidthH;
1423 4 : *pInnerSequenceY++ = fY-fHeightH;
1424 :
1425 4 : *pInnerSequenceX++ = fX-fWidthH;
1426 4 : *pInnerSequenceY++ = fY+fHeightH;
1427 :
1428 4 : *pInnerSequenceX++ = fX+fWidthH;
1429 4 : *pInnerSequenceY++ = fY-fHeightH;
1430 :
1431 4 : *pInnerSequenceX++ = fX+fWidthH;
1432 4 : *pInnerSequenceY++ = fY+fHeightH;
1433 :
1434 4 : *pInnerSequenceX++ = fX-fWidthH;
1435 4 : *pInnerSequenceY++ = fY-fHeightH;
1436 4 : break;
1437 : }
1438 : case Symbol_Sandglass:
1439 : {
1440 4 : *pInnerSequenceX++ = fX-fWidthH;
1441 4 : *pInnerSequenceY++ = fY+fHeightH;
1442 :
1443 4 : *pInnerSequenceX++ = fX+fWidthH;
1444 4 : *pInnerSequenceY++ = fY+fHeightH;
1445 :
1446 4 : *pInnerSequenceX++ = fX-fWidthH;
1447 4 : *pInnerSequenceY++ = fY-fHeightH;
1448 :
1449 :
1450 4 : *pInnerSequenceX++ = fX+fWidthH;
1451 4 : *pInnerSequenceY++ = fY-fHeightH;
1452 :
1453 4 : *pInnerSequenceX++ = fX-fWidthH;
1454 4 : *pInnerSequenceY++ = fY+fHeightH;
1455 4 : break;
1456 : }
1457 : case Symbol_Diamond:
1458 : {
1459 18 : *pInnerSequenceX++ = fX-fWidthH;
1460 18 : *pInnerSequenceY++ = fY;
1461 :
1462 18 : *pInnerSequenceX++ = fX;
1463 18 : *pInnerSequenceY++ = fY+fHeightH;
1464 :
1465 18 : *pInnerSequenceX++ = fX+fWidthH;
1466 18 : *pInnerSequenceY++ = fY;
1467 :
1468 18 : *pInnerSequenceX++ = fX;
1469 18 : *pInnerSequenceY++ = fY-fHeightH;
1470 :
1471 18 : *pInnerSequenceX++ = fX-fWidthH;
1472 18 : *pInnerSequenceY++ = fY;
1473 18 : break;
1474 : }
1475 : case Symbol_HorizontalBar:
1476 : {
1477 0 : *pInnerSequenceX++ = fX-fWidthH;
1478 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1479 :
1480 0 : *pInnerSequenceX++ = fX+fWidthH;
1481 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1482 :
1483 :
1484 0 : *pInnerSequenceX++ = fX+fWidthH;
1485 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1486 :
1487 0 : *pInnerSequenceX++ = fX-fWidthH;
1488 0 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1489 :
1490 0 : *pInnerSequenceX++ = fX-fWidthH;
1491 0 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1492 0 : break;
1493 : }
1494 : case Symbol_VerticalBar:
1495 : {
1496 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1497 0 : *pInnerSequenceY++ = fY-fHeightH;
1498 :
1499 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1500 0 : *pInnerSequenceY++ = fY-fHeightH;
1501 :
1502 :
1503 0 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1504 0 : *pInnerSequenceY++ = fY+fHeightH;
1505 :
1506 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1507 0 : *pInnerSequenceY++ = fY+fHeightH;
1508 :
1509 0 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1510 0 : *pInnerSequenceY++ = fY-fHeightH;
1511 :
1512 0 : break;
1513 : }
1514 : case Symbol_Circle:
1515 : {
1516 4 : double fOmega = 1.5707963267948966192 / (nQuarterCount + 1.0);
1517 : // one point in the middle of each edge to get full size bounding rectangle
1518 4 : *pInnerSequenceX++ = fX + fWidthH;
1519 4 : *pInnerSequenceY++ = fY;
1520 : // 0 to PI/2
1521 144 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1522 : {
1523 140 : *pInnerSequenceX++ = fX + fWidthH * cos( i * fOmega );
1524 140 : *pInnerSequenceY++ = fY - fHeightH * sin( i * fOmega );
1525 : }
1526 : // PI/2 to PI
1527 4 : *pInnerSequenceX++ = fX;
1528 4 : *pInnerSequenceY++ = fY - fHeightH;
1529 144 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1530 : {
1531 140 : *pInnerSequenceX++ = fX - fWidthH * sin( i * fOmega);
1532 140 : *pInnerSequenceY++ = fY - fHeightH * cos( i * fOmega);
1533 : }
1534 : // PI to 3/2*PI
1535 4 : *pInnerSequenceX++ = fX - fWidthH;
1536 4 : *pInnerSequenceY++ = fY;
1537 144 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1538 : {
1539 140 : *pInnerSequenceX++ = fX - fWidthH * cos( i * fOmega);
1540 140 : *pInnerSequenceY++ = fY + fHeightH * sin( i * fOmega);
1541 : }
1542 : // 3/2*PI to 2*PI
1543 4 : *pInnerSequenceX++ = fX;
1544 4 : *pInnerSequenceY++ = fY + fHeightH;
1545 144 : for (sal_Int32 i = 1; i <= nQuarterCount; ++i)
1546 : {
1547 140 : *pInnerSequenceX++ = fX + fWidthH * sin(i * fOmega);
1548 140 : *pInnerSequenceY++ = fY + fHeightH * cos(i * fOmega);
1549 : }
1550 : // close polygon
1551 4 : *pInnerSequenceX++ = fX + fWidthH;
1552 4 : *pInnerSequenceY++ = fY;
1553 4 : break;
1554 : }
1555 : case Symbol_Star:
1556 : {
1557 4 : *pInnerSequenceX++ = fX;
1558 4 : *pInnerSequenceY++ = fY-fHeightH;
1559 :
1560 4 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1561 4 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1562 :
1563 4 : *pInnerSequenceX++ = fX+fWidthH;
1564 4 : *pInnerSequenceY++ = fY;
1565 :
1566 4 : *pInnerSequenceX++ = fX+0.2*fWidthH;
1567 4 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1568 :
1569 4 : *pInnerSequenceX++ = fX;
1570 4 : *pInnerSequenceY++ = fY+fHeightH;
1571 :
1572 4 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1573 4 : *pInnerSequenceY++ = fY+0.2*fHeightH;
1574 :
1575 4 : *pInnerSequenceX++ = fX-fWidthH;
1576 4 : *pInnerSequenceY++ = fY;
1577 :
1578 4 : *pInnerSequenceX++ = fX-0.2*fWidthH;
1579 4 : *pInnerSequenceY++ = fY-0.2*fHeightH;
1580 :
1581 4 : *pInnerSequenceX++ = fX;
1582 4 : *pInnerSequenceY++ = fY-fHeightH;
1583 4 : break;
1584 : }
1585 : case Symbol_X:
1586 : {
1587 4 : const double fScaleX = fWidthH / 128.0;
1588 4 : const double fScaleY = fHeightH / 128.0;
1589 4 : const double fSmall = sqrt(200.0);
1590 4 : const double fLarge = 128.0 - fSmall;
1591 :
1592 4 : *pInnerSequenceX++ = fX;
1593 4 : *pInnerSequenceY++ = fY - fScaleY * fSmall;
1594 :
1595 4 : *pInnerSequenceX++ = fX - fScaleX * fLarge;
1596 4 : *pInnerSequenceY++ = fY - fHeightH;
1597 :
1598 4 : *pInnerSequenceX++ = fX - fWidthH;
1599 4 : *pInnerSequenceY++ = fY - fScaleY * fLarge;
1600 :
1601 4 : *pInnerSequenceX++ = fX - fScaleX * fSmall;
1602 4 : *pInnerSequenceY++ = fY;
1603 :
1604 4 : *pInnerSequenceX++ = fX - fWidthH;
1605 4 : *pInnerSequenceY++ = fY + fScaleY * fLarge;
1606 :
1607 4 : *pInnerSequenceX++ = fX - fScaleX * fLarge;
1608 4 : *pInnerSequenceY++ = fY + fHeightH;
1609 :
1610 4 : *pInnerSequenceX++ = fX;
1611 4 : *pInnerSequenceY++ = fY + fScaleY * fSmall;
1612 :
1613 4 : *pInnerSequenceX++ = fX + fScaleX * fLarge;
1614 4 : *pInnerSequenceY++ = fY + fHeightH;
1615 :
1616 4 : *pInnerSequenceX++ = fX + fWidthH;
1617 4 : *pInnerSequenceY++ = fY + fScaleY * fLarge;
1618 :
1619 4 : *pInnerSequenceX++ = fX + fScaleX * fSmall;
1620 4 : *pInnerSequenceY++ = fY;
1621 :
1622 4 : *pInnerSequenceX++ = fX + fWidthH;
1623 4 : *pInnerSequenceY++ = fY - fScaleY * fLarge;
1624 :
1625 4 : *pInnerSequenceX++ = fX + fScaleX * fLarge;
1626 4 : *pInnerSequenceY++ = fY - fHeightH;
1627 :
1628 4 : *pInnerSequenceX++ = fX;
1629 4 : *pInnerSequenceY++ = fY - fScaleY * fSmall;
1630 4 : break;
1631 :
1632 : }
1633 : case Symbol_Plus:
1634 : {
1635 4 : const double fScaleX = fWidthH / 128.0;
1636 4 : const double fScaleY = fHeightH / 128.0;
1637 4 : const double fHalf = 10.0; //half line width on 256 size square
1638 4 : const double fdX = fScaleX * fHalf;
1639 4 : const double fdY = fScaleY * fHalf;
1640 :
1641 4 : *pInnerSequenceX++ = fX-fdX;
1642 4 : *pInnerSequenceY++ = fY-fHeightH;
1643 :
1644 4 : *pInnerSequenceX++ = fX-fdX;
1645 4 : *pInnerSequenceY++ = fY-fdY;
1646 :
1647 4 : *pInnerSequenceX++ = fX-fWidthH;
1648 4 : *pInnerSequenceY++ = fY-fdY;
1649 :
1650 4 : *pInnerSequenceX++ = fX-fWidthH;
1651 4 : *pInnerSequenceY++ = fY+fdY;
1652 :
1653 4 : *pInnerSequenceX++ = fX-fdX;
1654 4 : *pInnerSequenceY++ = fY+fdY;
1655 :
1656 4 : *pInnerSequenceX++ = fX-fdX;
1657 4 : *pInnerSequenceY++ = fY+fHeightH;
1658 :
1659 4 : *pInnerSequenceX++ = fX+fdX;
1660 4 : *pInnerSequenceY++ = fY+fHeightH;
1661 :
1662 4 : *pInnerSequenceX++ = fX+fdX;
1663 4 : *pInnerSequenceY++ = fY+fdY;
1664 :
1665 4 : *pInnerSequenceX++ = fX+fWidthH;
1666 4 : *pInnerSequenceY++ = fY+fdY;
1667 :
1668 4 : *pInnerSequenceX++ = fX+fWidthH;
1669 4 : *pInnerSequenceY++ = fY-fdY;
1670 :
1671 4 : *pInnerSequenceX++ = fX+fdX;
1672 4 : *pInnerSequenceY++ = fY-fdY;
1673 :
1674 4 : *pInnerSequenceX++ = fX+fdY;
1675 4 : *pInnerSequenceY++ = fY-fHeightH;
1676 :
1677 4 : *pInnerSequenceX++ = fX-fdX;
1678 4 : *pInnerSequenceY++ = fY-fHeightH;
1679 4 : break;
1680 :
1681 : }
1682 : case Symbol_Asterisk:
1683 : {
1684 4 : const double fHalf = 10.0; // half line width on 256 size square
1685 4 : const double fTwoY = fHalf * sqrt(3.0);
1686 4 : const double fFourY = (128.0 - 2.0 * fHalf ) / sqrt(3.0);
1687 4 : const double fThreeX = 128.0 - fHalf;
1688 4 : const double fThreeY = fHalf * sqrt(3.0) + fFourY;
1689 4 : const double fFiveX = 2.0 * fHalf;
1690 :
1691 4 : const double fScaleX = fWidthH / 128.0;
1692 4 : const double fScaleY = fHeightH / 128.0;
1693 :
1694 : //1
1695 4 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1696 4 : *pInnerSequenceY++ = fY-fHeightH;
1697 : //2
1698 4 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1699 4 : *pInnerSequenceY++ = fY-fScaleY * fTwoY;
1700 : //3
1701 4 : *pInnerSequenceX++ = fX-fScaleX * fThreeX;
1702 4 : *pInnerSequenceY++ = fY-fScaleY * fThreeY;
1703 : //4
1704 4 : *pInnerSequenceX++ = fX-fWidthH;
1705 4 : *pInnerSequenceY++ = fY-fScaleY * fFourY;
1706 : //5
1707 4 : *pInnerSequenceX++ = fX-fScaleX * fFiveX;
1708 4 : *pInnerSequenceY++ = fY;
1709 : //6 as 4
1710 4 : *pInnerSequenceX++ = fX-fWidthH;
1711 4 : *pInnerSequenceY++ = fY+fScaleY * fFourY;
1712 : //7 as 3
1713 4 : *pInnerSequenceX++ = fX-fScaleX * fThreeX;
1714 4 : *pInnerSequenceY++ = fY+fScaleY * fThreeY;
1715 : //8 as 2
1716 4 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1717 4 : *pInnerSequenceY++ = fY+fScaleY * fTwoY;
1718 : //9 as 1
1719 4 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1720 4 : *pInnerSequenceY++ = fY+fHeightH;
1721 : //10 as 1
1722 4 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1723 4 : *pInnerSequenceY++ = fY+fHeightH;
1724 : //11 as 2
1725 4 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1726 4 : *pInnerSequenceY++ = fY+fScaleY * fTwoY;
1727 : //12 as 3
1728 4 : *pInnerSequenceX++ = fX+fScaleX * fThreeX;
1729 4 : *pInnerSequenceY++ = fY+fScaleY * fThreeY;
1730 : //13 as 4
1731 4 : *pInnerSequenceX++ = fX+fWidthH;
1732 4 : *pInnerSequenceY++ = fY+fScaleY * fFourY;
1733 : //14 as 5
1734 4 : *pInnerSequenceX++ = fX+fScaleX * fFiveX;
1735 4 : *pInnerSequenceY++ = fY;
1736 : //15 as 4
1737 4 : *pInnerSequenceX++ = fX+fWidthH;
1738 4 : *pInnerSequenceY++ = fY-fScaleY * fFourY;
1739 : //16 as 3
1740 4 : *pInnerSequenceX++ = fX+fScaleX * fThreeX;
1741 4 : *pInnerSequenceY++ = fY-fScaleY * fThreeY;
1742 : //17 as 2
1743 4 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1744 4 : *pInnerSequenceY++ = fY-fScaleY * fTwoY;
1745 : // 18 as 1
1746 4 : *pInnerSequenceX++ = fX+fScaleX * fHalf;
1747 4 : *pInnerSequenceY++ = fY-fHeightH;
1748 : // 19 = 1, closing
1749 4 : *pInnerSequenceX++ = fX-fScaleX * fHalf;
1750 4 : *pInnerSequenceY++ = fY-fHeightH;
1751 4 : break;
1752 : }
1753 : default: //case Symbol_Square:
1754 : {
1755 0 : *pInnerSequenceX++ = fX-fWidthH;
1756 0 : *pInnerSequenceY++ = fY-fHeightH;
1757 :
1758 0 : *pInnerSequenceX++ = fX-fWidthH;
1759 0 : *pInnerSequenceY++ = fY+fHeightH;
1760 :
1761 0 : *pInnerSequenceX++ = fX+fWidthH;
1762 0 : *pInnerSequenceY++ = fY+fHeightH;
1763 :
1764 0 : *pInnerSequenceX++ = fX+fWidthH;
1765 0 : *pInnerSequenceY++ = fY-fHeightH;
1766 :
1767 0 : *pInnerSequenceX++ = fX-fWidthH;
1768 0 : *pInnerSequenceY++ = fY-fHeightH;
1769 0 : break;
1770 : }
1771 : }
1772 :
1773 109 : return aPP;
1774 : }
1775 :
1776 : uno::Reference< drawing::XShape >
1777 109 : ShapeFactory::createSymbol2D(
1778 : const uno::Reference< drawing::XShapes >& xTarget
1779 : , const drawing::Position3D& rPosition
1780 : , const drawing::Direction3D& rSize
1781 : , sal_Int32 nStandardSymbol
1782 : , sal_Int32 nBorderColor
1783 : , sal_Int32 nFillColor )
1784 : {
1785 109 : if( !xTarget.is() )
1786 0 : return 0;
1787 :
1788 : //create shape
1789 : uno::Reference< drawing::XShape > xShape(
1790 109 : m_xShapeFactory->createInstance(
1791 109 : "com.sun.star.drawing.PolyPolygonShape" ), uno::UNO_QUERY );
1792 109 : xTarget->add(xShape);
1793 :
1794 : //set properties
1795 218 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1796 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1797 109 : if( xProp.is())
1798 : {
1799 : try
1800 : {
1801 : drawing::PointSequenceSequence aPoints( PolyToPointSequence(
1802 109 : createPolyPolygon_Symbol( rPosition, rSize, nStandardSymbol ) ));
1803 :
1804 : //Polygon
1805 109 : xProp->setPropertyValue( UNO_NAME_POLYPOLYGON
1806 109 : , uno::makeAny( aPoints ) );
1807 :
1808 : //LineColor
1809 109 : xProp->setPropertyValue( UNO_NAME_LINECOLOR
1810 109 : , uno::makeAny( nBorderColor ) );
1811 :
1812 : //FillColor
1813 109 : xProp->setPropertyValue( UNO_NAME_FILLCOLOR
1814 109 : , uno::makeAny( nFillColor ) );
1815 : }
1816 0 : catch( const uno::Exception& e )
1817 : {
1818 : ASSERT_EXCEPTION( e );
1819 : }
1820 : }
1821 218 : return xShape;
1822 : }
1823 :
1824 : uno::Reference< drawing::XShape >
1825 0 : ShapeFactory::createGraphic2D(
1826 : const uno::Reference< drawing::XShapes >& xTarget
1827 : , const drawing::Position3D& rPosition
1828 : , const drawing::Direction3D& rSize
1829 : , const uno::Reference< graphic::XGraphic >& xGraphic )
1830 : {
1831 0 : if( !xTarget.is() || !xGraphic.is() )
1832 0 : return 0;
1833 :
1834 : // @todo: change this to a rectangle shape with a fill bitmap for
1835 : // performance reasons (ask AW, said CL)
1836 :
1837 : //create shape
1838 : uno::Reference< drawing::XShape > xShape(
1839 0 : m_xShapeFactory->createInstance(
1840 0 : "com.sun.star.drawing.GraphicObjectShape" ), uno::UNO_QUERY );
1841 0 : xTarget->add(xShape);
1842 :
1843 : try
1844 : {
1845 : // assume position is upper left corner. Transform to center.
1846 : drawing::Position3D aCenterPosition(
1847 0 : rPosition.PositionX - (rSize.DirectionX / 2.0),
1848 0 : rPosition.PositionY - (rSize.DirectionY / 2.0),
1849 0 : rPosition.PositionZ );
1850 0 : xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1851 0 : xShape->setSize( Direction3DToAWTSize( rSize ));
1852 : }
1853 0 : catch( const uno::Exception & e )
1854 : {
1855 : ASSERT_EXCEPTION( e );
1856 : }
1857 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1858 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1859 0 : if( xProp.is())
1860 : {
1861 : try
1862 : {
1863 0 : xProp->setPropertyValue( "Graphic", uno::makeAny( xGraphic ));
1864 : }
1865 0 : catch( const uno::Exception& e )
1866 : {
1867 : ASSERT_EXCEPTION( e );
1868 : }
1869 : }
1870 0 : return xShape;
1871 : }
1872 :
1873 : uno::Reference< drawing::XShapes >
1874 15893 : ShapeFactory::createGroup2D( const uno::Reference< drawing::XShapes >& xTarget
1875 : , OUString aName )
1876 : {
1877 15893 : if( !xTarget.is() )
1878 0 : return 0;
1879 : try
1880 : {
1881 : //create and add to target
1882 : uno::Reference< drawing::XShape > xShape(
1883 15893 : m_xShapeFactory->createInstance(
1884 15893 : "com.sun.star.drawing.GroupShape" ), uno::UNO_QUERY );
1885 15893 : xTarget->add(xShape);
1886 :
1887 : //set name
1888 15893 : if(!aName.isEmpty())
1889 8649 : setShapeName( xShape , aName );
1890 :
1891 : {//workaround
1892 : //need this null size as otherwise empty group shapes where painted with a gray border
1893 15893 : xShape->setSize(awt::Size(0,0));
1894 : }
1895 :
1896 : //return
1897 : uno::Reference< drawing::XShapes > xShapes =
1898 31786 : uno::Reference<drawing::XShapes>( xShape, uno::UNO_QUERY );
1899 31786 : return xShapes;
1900 : }
1901 0 : catch( const uno::Exception& e )
1902 : {
1903 : ASSERT_EXCEPTION( e );
1904 : }
1905 0 : return 0;
1906 : }
1907 :
1908 : uno::Reference< drawing::XShapes >
1909 400 : ShapeFactory::createGroup3D( const uno::Reference< drawing::XShapes >& xTarget
1910 : , OUString aName )
1911 : {
1912 400 : if( !xTarget.is() )
1913 0 : return 0;
1914 : try
1915 : {
1916 : //create shape
1917 : uno::Reference< drawing::XShape > xShape(
1918 400 : m_xShapeFactory->createInstance(
1919 400 : "com.sun.star.drawing.Shape3DSceneObject" ), uno::UNO_QUERY );
1920 :
1921 400 : xTarget->add(xShape);
1922 :
1923 : //it is necessary to set the transform matrix to initialize the scene properly
1924 : //otherwise all objects which are placed into this Group will not be visible
1925 : //the following should be unnecessary after a the bug is fixed
1926 : {
1927 : //set properties
1928 400 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1929 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1930 400 : if( xProp.is())
1931 : {
1932 : try
1933 : {
1934 400 : ::basegfx::B3DHomMatrix aM;
1935 400 : xProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
1936 400 : , uno::makeAny(B3DHomMatrixToHomogenMatrix(aM)) );
1937 : }
1938 0 : catch( const uno::Exception& e )
1939 : {
1940 : ASSERT_EXCEPTION( e );
1941 : }
1942 400 : }
1943 : }
1944 :
1945 : //set name
1946 400 : if(!aName.isEmpty())
1947 298 : setShapeName( xShape , aName );
1948 :
1949 : //return
1950 : uno::Reference< drawing::XShapes > xShapes =
1951 800 : uno::Reference<drawing::XShapes>( xShape, uno::UNO_QUERY );
1952 800 : return xShapes;
1953 : }
1954 0 : catch( const uno::Exception& e )
1955 : {
1956 : ASSERT_EXCEPTION( e );
1957 : }
1958 0 : return 0;
1959 : }
1960 :
1961 : uno::Reference< drawing::XShape >
1962 0 : ShapeFactory::createCircle2D( const uno::Reference< drawing::XShapes >& xTarget
1963 : , const drawing::Position3D& rPosition
1964 : , const drawing::Direction3D& rSize )
1965 : {
1966 0 : if( !xTarget.is() )
1967 0 : return 0;
1968 :
1969 : //create shape
1970 : uno::Reference< drawing::XShape > xShape(
1971 0 : m_xShapeFactory->createInstance(
1972 0 : "com.sun.star.drawing.EllipseShape" ), uno::UNO_QUERY );
1973 0 : xTarget->add(xShape);
1974 :
1975 : try
1976 : {
1977 : drawing::Position3D aCenterPosition(
1978 0 : rPosition.PositionX - (rSize.DirectionX / 2.0),
1979 0 : rPosition.PositionY - (rSize.DirectionY / 2.0),
1980 0 : rPosition.PositionZ );
1981 0 : xShape->setPosition( Position3DToAWTPoint( aCenterPosition ));
1982 0 : xShape->setSize( Direction3DToAWTSize( rSize ));
1983 : }
1984 0 : catch( const uno::Exception & e )
1985 : {
1986 : ASSERT_EXCEPTION( e );
1987 : }
1988 :
1989 : //set properties
1990 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
1991 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
1992 0 : if( xProp.is())
1993 : {
1994 : try
1995 : {
1996 0 : drawing::CircleKind eKind = drawing::CircleKind_FULL;
1997 0 : xProp->setPropertyValue( UNO_NAME_CIRCKIND
1998 0 : , uno::makeAny( eKind ) );
1999 : }
2000 0 : catch( const uno::Exception& e )
2001 : {
2002 : ASSERT_EXCEPTION( e );
2003 : }
2004 : }
2005 0 : return xShape;
2006 : }
2007 :
2008 : uno::Reference< drawing::XShape >
2009 0 : ShapeFactory::createLine3D( const uno::Reference< drawing::XShapes >& xTarget
2010 : , const drawing::PolyPolygonShape3D& rPoints
2011 : , const VLineProperties& rLineProperties )
2012 : {
2013 0 : if( !xTarget.is() )
2014 0 : return 0;
2015 :
2016 0 : if(!rPoints.SequenceX.getLength())
2017 0 : return NULL;
2018 :
2019 : //create shape
2020 : uno::Reference< drawing::XShape > xShape(
2021 0 : m_xShapeFactory->createInstance(
2022 0 : "com.sun.star.drawing.Shape3DPolygonObject" ), uno::UNO_QUERY );
2023 0 : xTarget->add(xShape);
2024 :
2025 : //set properties
2026 0 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2027 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
2028 0 : if( xProp.is())
2029 : {
2030 : try
2031 : {
2032 : //Polygon
2033 0 : xProp->setPropertyValue( UNO_NAME_3D_POLYPOLYGON3D
2034 0 : , uno::makeAny( rPoints ) );
2035 :
2036 : //LineOnly
2037 0 : xProp->setPropertyValue( UNO_NAME_3D_LINEONLY
2038 0 : , uno::makeAny( (sal_Bool)true ) );
2039 :
2040 : //Transparency
2041 0 : if(rLineProperties.Transparence.hasValue())
2042 0 : xProp->setPropertyValue( UNO_NAME_LINETRANSPARENCE
2043 0 : , rLineProperties.Transparence );
2044 :
2045 : //LineStyle
2046 0 : if(rLineProperties.LineStyle.hasValue())
2047 0 : xProp->setPropertyValue( UNO_NAME_LINESTYLE
2048 0 : , rLineProperties.LineStyle );
2049 :
2050 : //LineWidth
2051 0 : if(rLineProperties.Width.hasValue())
2052 0 : xProp->setPropertyValue( UNO_NAME_LINEWIDTH
2053 0 : , rLineProperties.Width );
2054 :
2055 : //LineColor
2056 0 : if(rLineProperties.Color.hasValue())
2057 0 : xProp->setPropertyValue( UNO_NAME_LINECOLOR
2058 0 : , rLineProperties.Color );
2059 : //, uno::makeAny( sal_Int32( Color(COL_RED).GetColor()) ) );
2060 : }
2061 0 : catch( const uno::Exception& e )
2062 : {
2063 : ASSERT_EXCEPTION( e );
2064 : }
2065 : }
2066 0 : return xShape;
2067 : }
2068 :
2069 : uno::Reference< drawing::XShape >
2070 3133 : ShapeFactory::createLine2D( const uno::Reference< drawing::XShapes >& xTarget
2071 : , const drawing::PointSequenceSequence& rPoints
2072 : , const VLineProperties* pLineProperties )
2073 : {
2074 3133 : if( !xTarget.is() )
2075 0 : return 0;
2076 :
2077 3133 : if(!rPoints.getLength())
2078 0 : return NULL;
2079 :
2080 : //create shape
2081 : uno::Reference< drawing::XShape > xShape(
2082 3133 : m_xShapeFactory->createInstance(
2083 3133 : "com.sun.star.drawing.PolyLineShape" ), uno::UNO_QUERY );
2084 3133 : xTarget->add(xShape);
2085 :
2086 : //set properties
2087 6266 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2088 : OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
2089 3133 : if( xProp.is())
2090 : {
2091 : try
2092 : {
2093 : //Polygon
2094 3133 : xProp->setPropertyValue( UNO_NAME_POLYPOLYGON
2095 3133 : , uno::makeAny( rPoints ) );
2096 :
2097 3133 : if(pLineProperties)
2098 : {
2099 : //Transparency
2100 2875 : if(pLineProperties->Transparence.hasValue())
2101 2875 : xProp->setPropertyValue( UNO_NAME_LINETRANSPARENCE
2102 2875 : , pLineProperties->Transparence );
2103 :
2104 : //LineStyle
2105 2875 : if(pLineProperties->LineStyle.hasValue())
2106 2875 : xProp->setPropertyValue( UNO_NAME_LINESTYLE
2107 2875 : , pLineProperties->LineStyle );
2108 :
2109 : //LineWidth
2110 2875 : if(pLineProperties->Width.hasValue())
2111 2875 : xProp->setPropertyValue( UNO_NAME_LINEWIDTH
2112 2875 : , pLineProperties->Width );
2113 :
2114 : //LineColor
2115 2875 : if(pLineProperties->Color.hasValue())
2116 2875 : xProp->setPropertyValue( UNO_NAME_LINECOLOR
2117 2875 : , pLineProperties->Color );
2118 :
2119 : //LineDashName
2120 2875 : if(pLineProperties->DashName.hasValue())
2121 0 : xProp->setPropertyValue( "LineDashName"
2122 0 : , pLineProperties->DashName );
2123 : }
2124 : }
2125 0 : catch( const uno::Exception& e )
2126 : {
2127 : ASSERT_EXCEPTION( e );
2128 : }
2129 : }
2130 6266 : return xShape;
2131 : }
2132 :
2133 14853 : uno::Any ShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
2134 : {
2135 14853 : ::basegfx::B2DHomMatrix aM;
2136 : //As autogrow is active the rectangle is automatically expanded to that side
2137 : //to which the text is not adjusted.
2138 : // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
2139 14853 : aM.rotate( fRotationAnglePi );
2140 14853 : aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
2141 14853 : uno::Any aATransformation = uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) );
2142 14853 : return aATransformation;
2143 : }
2144 :
2145 2877 : void ShapeFactory::makeShapeInvisible( const uno::Reference< drawing::XShape >& xShape )
2146 : {
2147 2877 : uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
2148 : OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
2149 2877 : if( xShapeProp.is())
2150 : {
2151 : try
2152 : {
2153 2877 : xShapeProp->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
2154 2877 : xShapeProp->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
2155 : }
2156 0 : catch( const uno::Exception& e )
2157 : {
2158 : ASSERT_EXCEPTION( e );
2159 : }
2160 2877 : }
2161 2877 : }
2162 :
2163 2864 : uno::Reference< drawing::XShape > ShapeFactory::createInvisibleRectangle(
2164 : const uno::Reference< drawing::XShapes >& xTarget
2165 : , const awt::Size& rSize )
2166 : {
2167 : try
2168 : {
2169 2864 : if(!xTarget.is())
2170 0 : return 0;
2171 :
2172 2864 : uno::Reference< drawing::XShape > xShape( m_xShapeFactory->createInstance(
2173 2864 : "com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY );
2174 2864 : if( xTarget.is() && xShape.is())
2175 : {
2176 2864 : xTarget->add( xShape );
2177 2864 : ShapeFactory::makeShapeInvisible( xShape );
2178 2864 : xShape->setSize( rSize );
2179 : }
2180 2864 : return xShape;
2181 : }
2182 0 : catch( const uno::Exception & ex )
2183 : {
2184 : ASSERT_EXCEPTION( ex );
2185 : }
2186 0 : return 0;
2187 : }
2188 :
2189 : uno::Reference< drawing::XShape >
2190 9685 : ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget
2191 : , const OUString& rText
2192 : , const tNameSequence& rPropNames
2193 : , const tAnySequence& rPropValues
2194 : , const uno::Any& rATransformation )
2195 : {
2196 9685 : if( !xTarget.is() )
2197 0 : return 0;
2198 :
2199 9685 : if(rText.isEmpty())
2200 0 : return 0;
2201 :
2202 : //create shape and add to page
2203 : uno::Reference< drawing::XShape > xShape(
2204 9685 : m_xShapeFactory->createInstance(
2205 9685 : "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY );
2206 9685 : xTarget->add(xShape);
2207 :
2208 : //set text
2209 19370 : uno::Reference< text::XTextRange > xTextRange( xShape, uno::UNO_QUERY );
2210 9685 : if( xTextRange.is() )
2211 9685 : xTextRange->setString( rText );
2212 :
2213 19370 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
2214 9685 : if( xProp.is() )
2215 : {
2216 : //set properties
2217 9685 : PropertyMapper::setMultiProperties( rPropNames, rPropValues, xProp );
2218 :
2219 : //set position matrix
2220 : //the matrix needs to be set at the end behind autogrow and such position influencing properties
2221 : try
2222 : {
2223 9685 : xProp->setPropertyValue( "Transformation", rATransformation );
2224 : }
2225 0 : catch( const uno::Exception& e )
2226 : {
2227 : ASSERT_EXCEPTION( e );
2228 : }
2229 : }
2230 19370 : return xShape;
2231 : }
2232 :
2233 8816 : OUString ShapeFactory::getStackedString( const OUString& rString, bool bStacked )
2234 : {
2235 8816 : sal_Int32 nLen = rString.getLength();
2236 8816 : if(!bStacked || !nLen)
2237 8770 : return rString;
2238 :
2239 46 : OUStringBuffer aStackStr;
2240 :
2241 : //add a newline after each letter
2242 : //as we do not no letters here add a newline after each char
2243 178 : for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
2244 : {
2245 132 : if( nPosSrc )
2246 86 : aStackStr.append( sal_Unicode('\r') );
2247 132 : aStackStr.append(rString[nPosSrc]);
2248 : }
2249 46 : return aStackStr.makeStringAndClear();
2250 : }
2251 :
2252 142 : bool ShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D& rPoly)
2253 : {
2254 : // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
2255 142 : for( sal_Int32 nIdx = 0, nCount = rPoly.SequenceX.getLength(); nIdx < nCount; ++nIdx )
2256 142 : if( rPoly.SequenceX[ nIdx ].getLength() > 1 )
2257 142 : return true;
2258 0 : return false;
2259 : }
2260 :
2261 0 : bool ShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D& rPoly)
2262 : {
2263 : // true, if empty polypolygon or one polygon with one point
2264 0 : return (rPoly.SequenceX.getLength() == 0) ||
2265 0 : ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
2266 : }
2267 :
2268 0 : void ShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
2269 : {
2270 : OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "ShapeFactory::closePolygon - single polygon expected" );
2271 : //add a last point == first point
2272 0 : if(isPolygonEmptyOrSinglePoint(rPoly))
2273 0 : return;
2274 0 : drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
2275 0 : AddPointToPoly( rPoly, aFirst );
2276 : }
2277 :
2278 52 : awt::Size ShapeFactory::calculateNewSizeRespectingAspectRatio(
2279 : const awt::Size& rTargetSize
2280 : , const awt::Size& rSourceSizeWithCorrectAspectRatio )
2281 : {
2282 52 : awt::Size aNewSize;
2283 :
2284 52 : double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
2285 52 : double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
2286 52 : double fFactor = std::min(fFactorWidth,fFactorHeight);
2287 52 : aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
2288 52 : aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
2289 :
2290 52 : return aNewSize;
2291 : }
2292 :
2293 52 : awt::Point ShapeFactory::calculateTopLeftPositionToCenterObject(
2294 : const awt::Point& rTargetAreaPosition
2295 : , const awt::Size& rTargetAreaSize
2296 : , const awt::Size& rObjectSize )
2297 : {
2298 52 : awt::Point aNewPosition(rTargetAreaPosition);
2299 52 : aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
2300 52 : aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
2301 52 : return aNewPosition;
2302 : }
2303 :
2304 1049 : ::basegfx::B2IRectangle ShapeFactory::getRectangleOfShape(
2305 : const uno::Reference< drawing::XShape >& xShape )
2306 : {
2307 1049 : ::basegfx::B2IRectangle aRet;
2308 :
2309 1049 : if( xShape.is() )
2310 : {
2311 1049 : awt::Point aPos = xShape->getPosition();
2312 1049 : awt::Size aSize = xShape->getSize();
2313 1049 : aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
2314 : }
2315 1049 : return aRet;
2316 :
2317 : }
2318 :
2319 9234 : awt::Size ShapeFactory::getSizeAfterRotation(
2320 : const uno::Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
2321 : {
2322 9234 : awt::Size aRet(0,0);
2323 9234 : if(xShape.is())
2324 : {
2325 9234 : const awt::Size aSize( xShape->getSize() );
2326 :
2327 9234 : if( ::rtl::math::approxEqual( fRotationAngleDegree, 0.0 ) )
2328 9108 : aRet = aSize;
2329 : else
2330 : {
2331 252 : while(fRotationAngleDegree>=360.0)
2332 0 : fRotationAngleDegree-=360.0;
2333 252 : while(fRotationAngleDegree<0.0)
2334 0 : fRotationAngleDegree+=360.0;
2335 126 : if(fRotationAngleDegree>270.0)
2336 0 : fRotationAngleDegree=360.0-fRotationAngleDegree;
2337 126 : else if(fRotationAngleDegree>180.0)
2338 0 : fRotationAngleDegree=fRotationAngleDegree-180.0;
2339 126 : else if(fRotationAngleDegree>90.0)
2340 0 : fRotationAngleDegree=180.0-fRotationAngleDegree;
2341 :
2342 126 : const double fAnglePi = fRotationAngleDegree*F_PI/180.0;
2343 :
2344 : aRet.Height = static_cast<sal_Int32>(
2345 126 : aSize.Width*rtl::math::sin( fAnglePi )
2346 126 : + aSize.Height*rtl::math::cos( fAnglePi ));
2347 : aRet.Width = static_cast<sal_Int32>(
2348 126 : aSize.Width*rtl::math::cos( fAnglePi )
2349 126 : + aSize.Height*rtl::math::sin( fAnglePi ));
2350 : }
2351 : }
2352 9234 : return aRet;
2353 : }
2354 :
2355 26 : void ShapeFactory::removeSubShapes( const uno::Reference< drawing::XShapes >& xShapes )
2356 : {
2357 26 : if( xShapes.is() )
2358 : {
2359 26 : sal_Int32 nSubCount = xShapes->getCount();
2360 26 : uno::Reference< drawing::XShape > xShape;
2361 117 : for( sal_Int32 nS = nSubCount; nS--; )
2362 : {
2363 65 : if( xShapes->getByIndex( nS ) >>= xShape )
2364 65 : xShapes->remove( xShape );
2365 26 : }
2366 : }
2367 26 : }
2368 :
2369 : //.............................................................................
2370 33 : } //namespace chart
2371 : //.............................................................................
2372 :
2373 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|