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 :
10 : #include "macros.hxx"
11 : #include "PropertyMapper.hxx"
12 : #include "CommonConverters.hxx"
13 :
14 : #include "AbstractShapeFactory.hxx"
15 : #include <com/sun/star/beans/XPropertySet.hpp>
16 : #include <com/sun/star/drawing/CircleKind.hpp>
17 : #include <com/sun/star/drawing/DoubleSequence.hpp>
18 : #include <com/sun/star/drawing/FlagSequence.hpp>
19 : #include <com/sun/star/drawing/FillStyle.hpp>
20 : #include <com/sun/star/drawing/LineStyle.hpp>
21 : #include <com/sun/star/drawing/NormalsKind.hpp>
22 : #include <com/sun/star/drawing/PointSequence.hpp>
23 : #include <com/sun/star/drawing/PolygonKind.hpp>
24 : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
25 : #include <com/sun/star/drawing/ProjectionMode.hpp>
26 : #include <com/sun/star/drawing/ShadeMode.hpp>
27 : #include <com/sun/star/drawing/TextFitToSizeType.hpp>
28 : #include <com/sun/star/drawing/TextureProjectionMode.hpp>
29 : #include <com/sun/star/text/XText.hpp>
30 : #include <com/sun/star/uno/Any.hxx>
31 :
32 : #include <editeng/unoprnms.hxx>
33 : #include <rtl/math.hxx>
34 : #include <svx/svdocirc.hxx>
35 : #include <svx/svdopath.hxx>
36 : #include <vcl/svapp.hxx>
37 :
38 : #include <basegfx/point/b2dpoint.hxx>
39 : #include <basegfx/matrix/b2dhommatrix.hxx>
40 : #include <basegfx/matrix/b3dhommatrix.hxx>
41 :
42 : #include <osl/module.hxx>
43 :
44 : #include "OpenglShapeFactory.hxx"
45 : #include "ShapeFactory.hxx"
46 :
47 : using namespace com::sun::star;
48 : using ::com::sun::star::uno::Reference;
49 :
50 : namespace chart {
51 :
52 : namespace {
53 :
54 : typedef opengl::OpenglShapeFactory* (*__getOpenglShapeFactory)(void);
55 :
56 : #ifndef DISABLE_DYNLOADING
57 :
58 0 : static void SAL_CALL thisModule() {}
59 :
60 0 : osl::Module* getOpenGLModule()
61 : {
62 0 : static osl::Module aModule;
63 0 : if (aModule.is())
64 : // Already loaded.
65 0 : return &aModule;
66 :
67 0 : OUString aLibName(SVLIBRARY("chartopengl"));
68 0 : bool bLoaded = aModule.loadRelative(&thisModule, aLibName);
69 0 : if (!bLoaded)
70 0 : bLoaded = aModule.load(aLibName);
71 :
72 0 : return bLoaded ? &aModule : NULL;
73 : }
74 :
75 : #endif
76 :
77 : }
78 :
79 : #ifdef DISABLE_DYNLOADING
80 : extern "C" opengl::OpenglShapeFactory* getOpenglShapeFactory();
81 : #endif
82 :
83 24079 : AbstractShapeFactory* AbstractShapeFactory::getOrCreateShapeFactory(uno::Reference< lang::XMultiServiceFactory> xFactory)
84 : {
85 : static AbstractShapeFactory* pShapeFactory = NULL;
86 :
87 24079 : if(pShapeFactory)
88 24051 : return pShapeFactory;
89 :
90 28 : if(getenv("CHART_DUMMY_FACTORY") && !Application::IsHeadlessModeEnabled())
91 : {
92 : #ifndef DISABLE_DYNLOADING
93 0 : osl::Module* pModule = getOpenGLModule();
94 0 : if(pModule)
95 : {
96 0 : oslGenericFunction fn = pModule->getFunctionSymbol("getOpenglShapeFactory");
97 0 : if(fn)
98 : {
99 :
100 0 : pShapeFactory = reinterpret_cast<__getOpenglShapeFactory>(fn)();
101 0 : pShapeFactory->setShapeFactory(xFactory);
102 : }
103 : }
104 : #elif defined(IOS) || defined(ANDROID) // Library_chartopengl is not portable enough yet
105 : pShapeFactory = NULL;
106 : #else
107 : pShapeFactory = getOpenglShapeFactory();
108 : pShapeFactory->setShapeFactory(xFactory);
109 : #endif
110 : }
111 :
112 28 : if(!pShapeFactory)
113 28 : pShapeFactory = new ShapeFactory(xFactory);
114 :
115 28 : return pShapeFactory;
116 : }
117 :
118 446 : sal_Int32 AbstractShapeFactory::getSymbolCount()
119 : {
120 446 : return Symbol_COUNT;
121 : }
122 :
123 2756 : uno::Reference< drawing::XShapes > AbstractShapeFactory::getChartRootShape(
124 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
125 : {
126 2756 : uno::Reference< drawing::XShapes > xRet;
127 5512 : uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
128 2756 : if( xShapes.is() )
129 : {
130 2756 : sal_Int32 nCount = xShapes->getCount();
131 2756 : uno::Reference< drawing::XShape > xShape;
132 5512 : for( sal_Int32 nN = nCount; nN--; )
133 : {
134 1024 : if( xShapes->getByIndex( nN ) >>= xShape )
135 : {
136 1024 : if( AbstractShapeFactory::getShapeName( xShape ).equals("com.sun.star.chart2.shapes") )
137 : {
138 1024 : xRet = uno::Reference< drawing::XShapes >( xShape, uno::UNO_QUERY );
139 1024 : break;
140 : }
141 : }
142 2756 : }
143 : }
144 5512 : return xRet;
145 : }
146 :
147 2997 : void AbstractShapeFactory::makeShapeInvisible( const uno::Reference< drawing::XShape >& xShape )
148 : {
149 2997 : uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
150 : OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
151 2997 : if( xShapeProp.is())
152 : {
153 : try
154 : {
155 2997 : xShapeProp->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
156 2997 : xShapeProp->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
157 : }
158 0 : catch( const uno::Exception& e )
159 : {
160 : ASSERT_EXCEPTION( e );
161 : }
162 2997 : }
163 2997 : }
164 :
165 : // set a name/CID at a shape (is used for selection handling)
166 :
167 23146 : void AbstractShapeFactory::setShapeName( const uno::Reference< drawing::XShape >& xShape
168 : , const OUString& rName )
169 : {
170 23146 : if(!xShape.is())
171 23146 : return;
172 23146 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
173 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
174 23146 : if( xProp.is())
175 : {
176 : try
177 : {
178 23146 : xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
179 23146 : , uno::makeAny( rName ) );
180 : }
181 0 : catch( const uno::Exception& e )
182 : {
183 : ASSERT_EXCEPTION( e );
184 : }
185 23146 : }
186 : }
187 :
188 1024 : OUString AbstractShapeFactory::getShapeName( const uno::Reference< drawing::XShape >& xShape )
189 : {
190 1024 : OUString aRet;
191 :
192 2048 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
193 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
194 1024 : if( xProp.is())
195 : {
196 : try
197 : {
198 1024 : xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
199 : }
200 0 : catch( const uno::Exception& e )
201 : {
202 : ASSERT_EXCEPTION( e );
203 : }
204 : }
205 :
206 2048 : return aRet;
207 : }
208 :
209 18562 : uno::Any AbstractShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
210 : {
211 18562 : ::basegfx::B2DHomMatrix aM;
212 : //As autogrow is active the rectangle is automatically expanded to that side
213 : //to which the text is not adjusted.
214 : // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
215 18562 : aM.rotate( fRotationAnglePi );
216 18562 : aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
217 18562 : uno::Any aATransformation = uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) );
218 18562 : return aATransformation;
219 : }
220 :
221 10183 : OUString AbstractShapeFactory::getStackedString( const OUString& rString, bool bStacked )
222 : {
223 10183 : sal_Int32 nLen = rString.getLength();
224 10183 : if(!bStacked || !nLen)
225 10130 : return rString;
226 :
227 53 : OUStringBuffer aStackStr;
228 :
229 : //add a newline after each letter
230 : //as we do not no letters here add a newline after each char
231 244 : for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
232 : {
233 191 : if( nPosSrc )
234 138 : aStackStr.append( '\r' );
235 191 : aStackStr.append(rString[nPosSrc]);
236 : }
237 53 : return aStackStr.makeStringAndClear();
238 : }
239 :
240 321 : bool AbstractShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D& rPoly)
241 : {
242 : // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
243 321 : for( sal_Int32 nIdx = 0, nCount = rPoly.SequenceX.getLength(); nIdx < nCount; ++nIdx )
244 321 : if( rPoly.SequenceX[ nIdx ].getLength() > 1 )
245 321 : return true;
246 0 : return false;
247 : }
248 :
249 16 : bool AbstractShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D& rPoly)
250 : {
251 : // true, if empty polypolygon or one polygon with one point
252 32 : return (rPoly.SequenceX.getLength() == 0) ||
253 48 : ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
254 : }
255 :
256 16 : void AbstractShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
257 : {
258 : OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "AbstractShapeFactory::closePolygon - single polygon expected" );
259 : //add a last point == first point
260 16 : if(isPolygonEmptyOrSinglePoint(rPoly))
261 16 : return;
262 16 : drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
263 16 : AddPointToPoly( rPoly, aFirst );
264 : }
265 :
266 180 : awt::Size AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
267 : const awt::Size& rTargetSize
268 : , const awt::Size& rSourceSizeWithCorrectAspectRatio )
269 : {
270 180 : awt::Size aNewSize;
271 :
272 180 : double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
273 180 : double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
274 180 : double fFactor = std::min(fFactorWidth,fFactorHeight);
275 180 : aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
276 180 : aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
277 :
278 180 : return aNewSize;
279 : }
280 :
281 180 : awt::Point AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
282 : const awt::Point& rTargetAreaPosition
283 : , const awt::Size& rTargetAreaSize
284 : , const awt::Size& rObjectSize )
285 : {
286 180 : awt::Point aNewPosition(rTargetAreaPosition);
287 180 : aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
288 180 : aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
289 180 : return aNewPosition;
290 : }
291 :
292 1068 : ::basegfx::B2IRectangle AbstractShapeFactory::getRectangleOfShape(
293 : const uno::Reference< drawing::XShape >& xShape )
294 : {
295 1068 : ::basegfx::B2IRectangle aRet;
296 :
297 1068 : if( xShape.is() )
298 : {
299 1068 : awt::Point aPos = xShape->getPosition();
300 1068 : awt::Size aSize = xShape->getSize();
301 1068 : aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
302 : }
303 1068 : return aRet;
304 :
305 : }
306 :
307 10102 : awt::Size AbstractShapeFactory::getSizeAfterRotation(
308 : const uno::Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
309 : {
310 10102 : awt::Size aRet(0,0);
311 10102 : if(xShape.is())
312 : {
313 10102 : const awt::Size aSize( xShape->getSize() );
314 :
315 10102 : if( ::rtl::math::approxEqual( fRotationAngleDegree, 0.0 ) )
316 9981 : aRet = aSize;
317 : else
318 : {
319 242 : while(fRotationAngleDegree>=360.0)
320 0 : fRotationAngleDegree-=360.0;
321 242 : while(fRotationAngleDegree<0.0)
322 0 : fRotationAngleDegree+=360.0;
323 121 : if(fRotationAngleDegree>270.0)
324 8 : fRotationAngleDegree=360.0-fRotationAngleDegree;
325 113 : else if(fRotationAngleDegree>180.0)
326 0 : fRotationAngleDegree=fRotationAngleDegree-180.0;
327 113 : else if(fRotationAngleDegree>90.0)
328 0 : fRotationAngleDegree=180.0-fRotationAngleDegree;
329 :
330 121 : const double fAnglePi = fRotationAngleDegree*F_PI/180.0;
331 :
332 : aRet.Height = static_cast<sal_Int32>(
333 121 : aSize.Width*rtl::math::sin( fAnglePi )
334 121 : + aSize.Height*rtl::math::cos( fAnglePi ));
335 : aRet.Width = static_cast<sal_Int32>(
336 121 : aSize.Width*rtl::math::cos( fAnglePi )
337 121 : + aSize.Height*rtl::math::sin( fAnglePi ));
338 : }
339 : }
340 10102 : return aRet;
341 : }
342 :
343 40 : void AbstractShapeFactory::removeSubShapes( const uno::Reference< drawing::XShapes >& xShapes )
344 : {
345 40 : if( xShapes.is() )
346 : {
347 40 : sal_Int32 nSubCount = xShapes->getCount();
348 40 : uno::Reference< drawing::XShape > xShape;
349 180 : for( sal_Int32 nS = nSubCount; nS--; )
350 : {
351 100 : if( xShapes->getByIndex( nS ) >>= xShape )
352 100 : xShapes->remove( xShape );
353 40 : }
354 : }
355 40 : }
356 :
357 108 : }
358 :
359 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|