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