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 40334 : AbstractShapeFactory* AbstractShapeFactory::getOrCreateShapeFactory(uno::Reference< lang::XMultiServiceFactory> xFactory)
84 : {
85 : static AbstractShapeFactory* pShapeFactory = NULL;
86 :
87 40334 : if(pShapeFactory)
88 40318 : return pShapeFactory;
89 :
90 16 : 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 16 : if(!pShapeFactory)
113 16 : pShapeFactory = new ShapeFactory(xFactory);
114 :
115 16 : return pShapeFactory;
116 : }
117 :
118 1990 : uno::Reference< drawing::XShapes > AbstractShapeFactory::getChartRootShape(
119 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
120 : {
121 1990 : uno::Reference< drawing::XShapes > xRet;
122 3980 : uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
123 1990 : if( xShapes.is() )
124 : {
125 1990 : sal_Int32 nCount = xShapes->getCount();
126 1990 : uno::Reference< drawing::XShape > xShape;
127 3980 : for( sal_Int32 nN = nCount; nN--; )
128 : {
129 1204 : if( xShapes->getByIndex( nN ) >>= xShape )
130 : {
131 1204 : if( AbstractShapeFactory::getShapeName( xShape ) == "com.sun.star.chart2.shapes" )
132 : {
133 1204 : xRet = uno::Reference< drawing::XShapes >( xShape, uno::UNO_QUERY );
134 1204 : break;
135 : }
136 : }
137 1990 : }
138 : }
139 3980 : return xRet;
140 : }
141 :
142 5127 : void AbstractShapeFactory::makeShapeInvisible( const uno::Reference< drawing::XShape >& xShape )
143 : {
144 5127 : uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
145 : OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
146 5127 : if( xShapeProp.is())
147 : {
148 : try
149 : {
150 5127 : xShapeProp->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
151 5127 : xShapeProp->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
152 : }
153 0 : catch( const uno::Exception& e )
154 : {
155 : ASSERT_EXCEPTION( e );
156 : }
157 5127 : }
158 5127 : }
159 :
160 : // set a name/CID at a shape (is used for selection handling)
161 :
162 37969 : void AbstractShapeFactory::setShapeName( const uno::Reference< drawing::XShape >& xShape
163 : , const OUString& rName )
164 : {
165 37969 : if(!xShape.is())
166 37969 : return;
167 37969 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
168 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
169 37969 : if( xProp.is())
170 : {
171 : try
172 : {
173 37969 : xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
174 37969 : , uno::makeAny( rName ) );
175 : }
176 0 : catch( const uno::Exception& e )
177 : {
178 : ASSERT_EXCEPTION( e );
179 : }
180 37969 : }
181 : }
182 :
183 1204 : OUString AbstractShapeFactory::getShapeName( const uno::Reference< drawing::XShape >& xShape )
184 : {
185 1204 : OUString aRet;
186 :
187 2408 : uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
188 : OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
189 1204 : if( xProp.is())
190 : {
191 : try
192 : {
193 1204 : xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
194 : }
195 0 : catch( const uno::Exception& e )
196 : {
197 : ASSERT_EXCEPTION( e );
198 : }
199 : }
200 :
201 2408 : return aRet;
202 : }
203 :
204 28722 : uno::Any AbstractShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
205 : {
206 28722 : ::basegfx::B2DHomMatrix aM;
207 : //As autogrow is active the rectangle is automatically expanded to that side
208 : //to which the text is not adjusted.
209 : // aM.scale( 1, 1 ); Oops? A scale with this parameters is neutral, line commented out
210 28722 : aM.rotate( fRotationAnglePi );
211 28722 : aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
212 28722 : uno::Any aATransformation = uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) );
213 28722 : return aATransformation;
214 : }
215 :
216 16336 : OUString AbstractShapeFactory::getStackedString( const OUString& rString, bool bStacked )
217 : {
218 16336 : sal_Int32 nLen = rString.getLength();
219 16336 : if(!bStacked || !nLen)
220 16197 : return rString;
221 :
222 139 : OUStringBuffer aStackStr;
223 :
224 : //add a newline after each letter
225 : //as we do not no letters here add a newline after each char
226 624 : for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
227 : {
228 485 : if( nPosSrc )
229 346 : aStackStr.append( '\r' );
230 485 : aStackStr.append(rString[nPosSrc]);
231 : }
232 139 : return aStackStr.makeStringAndClear();
233 : }
234 :
235 328 : bool AbstractShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D& rPoly)
236 : {
237 : // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
238 332 : for( sal_Int32 nIdx = 0, nCount = rPoly.SequenceX.getLength(); nIdx < nCount; ++nIdx )
239 330 : if( rPoly.SequenceX[ nIdx ].getLength() > 1 )
240 326 : return true;
241 2 : return false;
242 : }
243 :
244 108 : bool AbstractShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D& rPoly)
245 : {
246 : // true, if empty polypolygon or one polygon with one point
247 216 : return (rPoly.SequenceX.getLength() == 0) ||
248 324 : ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
249 : }
250 :
251 104 : void AbstractShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
252 : {
253 : OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "AbstractShapeFactory::closePolygon - single polygon expected" );
254 : //add a last point == first point
255 104 : if(isPolygonEmptyOrSinglePoint(rPoly))
256 104 : return;
257 104 : drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
258 104 : AddPointToPoly( rPoly, aFirst );
259 : }
260 :
261 278 : awt::Size AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
262 : const awt::Size& rTargetSize
263 : , const awt::Size& rSourceSizeWithCorrectAspectRatio )
264 : {
265 278 : awt::Size aNewSize;
266 :
267 278 : double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
268 278 : double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
269 278 : double fFactor = std::min(fFactorWidth,fFactorHeight);
270 278 : aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
271 278 : aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
272 :
273 278 : return aNewSize;
274 : }
275 :
276 278 : awt::Point AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
277 : const awt::Point& rTargetAreaPosition
278 : , const awt::Size& rTargetAreaSize
279 : , const awt::Size& rObjectSize )
280 : {
281 278 : awt::Point aNewPosition(rTargetAreaPosition);
282 278 : aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
283 278 : aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
284 278 : return aNewPosition;
285 : }
286 :
287 2069 : ::basegfx::B2IRectangle AbstractShapeFactory::getRectangleOfShape(
288 : const uno::Reference< drawing::XShape >& xShape )
289 : {
290 2069 : ::basegfx::B2IRectangle aRet;
291 :
292 2069 : if( xShape.is() )
293 : {
294 2069 : awt::Point aPos = xShape->getPosition();
295 2069 : awt::Size aSize = xShape->getSize();
296 2069 : aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
297 : }
298 2069 : return aRet;
299 :
300 : }
301 :
302 16134 : awt::Size AbstractShapeFactory::getSizeAfterRotation(
303 : const uno::Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
304 : {
305 16134 : awt::Size aRet(0,0);
306 16134 : if(xShape.is())
307 : {
308 16134 : const awt::Size aSize( xShape->getSize() );
309 :
310 16134 : if( ::rtl::math::approxEqual( fRotationAngleDegree, 0.0 ) )
311 15726 : aRet = aSize;
312 : else
313 : {
314 816 : while(fRotationAngleDegree>=360.0)
315 0 : fRotationAngleDegree-=360.0;
316 816 : while(fRotationAngleDegree<0.0)
317 0 : fRotationAngleDegree+=360.0;
318 408 : if(fRotationAngleDegree>270.0)
319 5 : fRotationAngleDegree=360.0-fRotationAngleDegree;
320 403 : else if(fRotationAngleDegree>180.0)
321 2 : fRotationAngleDegree=fRotationAngleDegree-180.0;
322 401 : else if(fRotationAngleDegree>90.0)
323 0 : fRotationAngleDegree=180.0-fRotationAngleDegree;
324 :
325 408 : const double fAnglePi = fRotationAngleDegree*F_PI/180.0;
326 :
327 : aRet.Height = static_cast<sal_Int32>(
328 408 : aSize.Width*rtl::math::sin( fAnglePi )
329 408 : + aSize.Height*rtl::math::cos( fAnglePi ));
330 : aRet.Width = static_cast<sal_Int32>(
331 408 : aSize.Width*rtl::math::cos( fAnglePi )
332 408 : + aSize.Height*rtl::math::sin( fAnglePi ));
333 : }
334 : }
335 16134 : return aRet;
336 : }
337 :
338 74 : void AbstractShapeFactory::removeSubShapes( const uno::Reference< drawing::XShapes >& xShapes )
339 : {
340 74 : if( xShapes.is() )
341 : {
342 74 : sal_Int32 nSubCount = xShapes->getCount();
343 74 : uno::Reference< drawing::XShape > xShape;
344 333 : for( sal_Int32 nS = nSubCount; nS--; )
345 : {
346 185 : if( xShapes->getByIndex( nS ) >>= xShape )
347 185 : xShapes->remove( xShape );
348 74 : }
349 : }
350 74 : }
351 :
352 57 : }
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|