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