fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / view / main / AbstractShapeFactory.cxx
blobc8e22958060560d6b568b587d3ff442d81b2569f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include "macros.hxx"
11 #include "PropertyMapper.hxx"
12 #include "CommonConverters.hxx"
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>
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>
38 #include <basegfx/point/b2dpoint.hxx>
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <basegfx/matrix/b3dhommatrix.hxx>
42 #include <osl/module.hxx>
44 #include "OpenglShapeFactory.hxx"
45 #include "ShapeFactory.hxx"
47 using namespace com::sun::star;
48 using ::com::sun::star::uno::Reference;
50 namespace chart {
52 namespace {
54 typedef opengl::OpenglShapeFactory* (*__getOpenglShapeFactory)(void);
56 #ifndef DISABLE_DYNLOADING
58 static void SAL_CALL thisModule() {}
60 osl::Module* getOpenGLModule()
62 static osl::Module aModule;
63 if (aModule.is())
64 // Already loaded.
65 return &aModule;
67 OUString aLibName(SVLIBRARY("chartopengl"));
68 bool bLoaded = aModule.loadRelative(&thisModule, aLibName);
69 if (!bLoaded)
70 bLoaded = aModule.load(aLibName);
72 return bLoaded ? &aModule : NULL;
75 #endif
79 #ifdef DISABLE_DYNLOADING
80 extern "C" opengl::OpenglShapeFactory* getOpenglShapeFactory();
81 #endif
83 AbstractShapeFactory* AbstractShapeFactory::getOrCreateShapeFactory(uno::Reference< lang::XMultiServiceFactory> xFactory)
85 static AbstractShapeFactory* pShapeFactory = NULL;
87 if(pShapeFactory)
88 return pShapeFactory;
90 if(getenv("CHART_DUMMY_FACTORY") && !Application::IsHeadlessModeEnabled())
92 #ifndef DISABLE_DYNLOADING
93 osl::Module* pModule = getOpenGLModule();
94 if(pModule)
96 oslGenericFunction fn = pModule->getFunctionSymbol("getOpenglShapeFactory");
97 if(fn)
100 pShapeFactory = reinterpret_cast<__getOpenglShapeFactory>(fn)();
101 pShapeFactory->setShapeFactory(xFactory);
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
112 if(!pShapeFactory)
113 pShapeFactory = new ShapeFactory(xFactory);
115 return pShapeFactory;
118 uno::Reference< drawing::XShapes > AbstractShapeFactory::getChartRootShape(
119 const uno::Reference< drawing::XDrawPage>& xDrawPage )
121 uno::Reference< drawing::XShapes > xRet;
122 uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
123 if( xShapes.is() )
125 sal_Int32 nCount = xShapes->getCount();
126 uno::Reference< drawing::XShape > xShape;
127 for( sal_Int32 nN = nCount; nN--; )
129 if( xShapes->getByIndex( nN ) >>= xShape )
131 if( AbstractShapeFactory::getShapeName( xShape ) == "com.sun.star.chart2.shapes" )
133 xRet = uno::Reference< drawing::XShapes >( xShape, uno::UNO_QUERY );
134 break;
139 return xRet;
142 void AbstractShapeFactory::makeShapeInvisible( const uno::Reference< drawing::XShape >& xShape )
144 uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY );
145 OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
146 if( xShapeProp.is())
150 xShapeProp->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
151 xShapeProp->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
153 catch( const uno::Exception& e )
155 ASSERT_EXCEPTION( e );
160 // set a name/CID at a shape (is used for selection handling)
162 void AbstractShapeFactory::setShapeName( const uno::Reference< drawing::XShape >& xShape
163 , const OUString& rName )
165 if(!xShape.is())
166 return;
167 uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
168 OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
169 if( xProp.is())
173 xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME
174 , uno::makeAny( rName ) );
176 catch( const uno::Exception& e )
178 ASSERT_EXCEPTION( e );
183 OUString AbstractShapeFactory::getShapeName( const uno::Reference< drawing::XShape >& xShape )
185 OUString aRet;
187 uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
188 OSL_ENSURE(xProp.is(), "shape offers no XPropertySet");
189 if( xProp.is())
193 xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
195 catch( const uno::Exception& e )
197 ASSERT_EXCEPTION( e );
201 return aRet;
204 uno::Any AbstractShapeFactory::makeTransformation( const awt::Point& rScreenPosition2D, double fRotationAnglePi )
206 ::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 aM.rotate( fRotationAnglePi );
211 aM.translate( rScreenPosition2D.X, rScreenPosition2D.Y );
212 uno::Any aATransformation = uno::makeAny( B2DHomMatrixToHomogenMatrix3(aM) );
213 return aATransformation;
216 OUString AbstractShapeFactory::getStackedString( const OUString& rString, bool bStacked )
218 sal_Int32 nLen = rString.getLength();
219 if(!bStacked || !nLen)
220 return rString;
222 OUStringBuffer aStackStr;
224 //add a newline after each letter
225 //as we do not no letters here add a newline after each char
226 for( sal_Int32 nPosSrc=0; nPosSrc < nLen; nPosSrc++ )
228 if( nPosSrc )
229 aStackStr.append( '\r' );
230 aStackStr.append(rString[nPosSrc]);
232 return aStackStr.makeStringAndClear();
235 bool AbstractShapeFactory::hasPolygonAnyLines( drawing::PolyPolygonShape3D& rPoly)
237 // #i67757# check all contained polygons, if at least one polygon contains 2 or more points, return true
238 for( sal_Int32 nIdx = 0, nCount = rPoly.SequenceX.getLength(); nIdx < nCount; ++nIdx )
239 if( rPoly.SequenceX[ nIdx ].getLength() > 1 )
240 return true;
241 return false;
244 bool AbstractShapeFactory::isPolygonEmptyOrSinglePoint( drawing::PolyPolygonShape3D& rPoly)
246 // true, if empty polypolygon or one polygon with one point
247 return (rPoly.SequenceX.getLength() == 0) ||
248 ((rPoly.SequenceX.getLength() == 1) && (rPoly.SequenceX[0].getLength() <= 1));
251 void AbstractShapeFactory::closePolygon( drawing::PolyPolygonShape3D& rPoly)
253 OSL_ENSURE( rPoly.SequenceX.getLength() <= 1, "AbstractShapeFactory::closePolygon - single polygon expected" );
254 //add a last point == first point
255 if(isPolygonEmptyOrSinglePoint(rPoly))
256 return;
257 drawing::Position3D aFirst(rPoly.SequenceX[0][0],rPoly.SequenceY[0][0],rPoly.SequenceZ[0][0]);
258 AddPointToPoly( rPoly, aFirst );
261 awt::Size AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
262 const awt::Size& rTargetSize
263 , const awt::Size& rSourceSizeWithCorrectAspectRatio )
265 awt::Size aNewSize;
267 double fFactorWidth = double(rTargetSize.Width)/double(rSourceSizeWithCorrectAspectRatio.Width);
268 double fFactorHeight = double(rTargetSize.Height)/double(rSourceSizeWithCorrectAspectRatio.Height);
269 double fFactor = std::min(fFactorWidth,fFactorHeight);
270 aNewSize.Width=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Width);
271 aNewSize.Height=static_cast<sal_Int32>(fFactor*rSourceSizeWithCorrectAspectRatio.Height);
273 return aNewSize;
276 awt::Point AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
277 const awt::Point& rTargetAreaPosition
278 , const awt::Size& rTargetAreaSize
279 , const awt::Size& rObjectSize )
281 awt::Point aNewPosition(rTargetAreaPosition);
282 aNewPosition.X += static_cast<sal_Int32>(double(rTargetAreaSize.Width-rObjectSize.Width)/2.0);
283 aNewPosition.Y += static_cast<sal_Int32>(double(rTargetAreaSize.Height-rObjectSize.Height)/2.0);
284 return aNewPosition;
287 ::basegfx::B2IRectangle AbstractShapeFactory::getRectangleOfShape(
288 const uno::Reference< drawing::XShape >& xShape )
290 ::basegfx::B2IRectangle aRet;
292 if( xShape.is() )
294 awt::Point aPos = xShape->getPosition();
295 awt::Size aSize = xShape->getSize();
296 aRet = BaseGFXHelper::makeRectangle(aPos,aSize);
298 return aRet;
302 awt::Size AbstractShapeFactory::getSizeAfterRotation(
303 const uno::Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
305 awt::Size aRet(0,0);
306 if(xShape.is())
308 const awt::Size aSize( xShape->getSize() );
310 if( ::rtl::math::approxEqual( fRotationAngleDegree, 0.0 ) )
311 aRet = aSize;
312 else
314 while(fRotationAngleDegree>=360.0)
315 fRotationAngleDegree-=360.0;
316 while(fRotationAngleDegree<0.0)
317 fRotationAngleDegree+=360.0;
318 if(fRotationAngleDegree>270.0)
319 fRotationAngleDegree=360.0-fRotationAngleDegree;
320 else if(fRotationAngleDegree>180.0)
321 fRotationAngleDegree=fRotationAngleDegree-180.0;
322 else if(fRotationAngleDegree>90.0)
323 fRotationAngleDegree=180.0-fRotationAngleDegree;
325 const double fAnglePi = fRotationAngleDegree*F_PI/180.0;
327 aRet.Height = static_cast<sal_Int32>(
328 aSize.Width*rtl::math::sin( fAnglePi )
329 + aSize.Height*rtl::math::cos( fAnglePi ));
330 aRet.Width = static_cast<sal_Int32>(
331 aSize.Width*rtl::math::cos( fAnglePi )
332 + aSize.Height*rtl::math::sin( fAnglePi ));
335 return aRet;
338 void AbstractShapeFactory::removeSubShapes( const uno::Reference< drawing::XShapes >& xShapes )
340 if( xShapes.is() )
342 sal_Int32 nSubCount = xShapes->getCount();
343 uno::Reference< drawing::XShape > xShape;
344 for( sal_Int32 nS = nSubCount; nS--; )
346 if( xShapes->getByIndex( nS ) >>= xShape )
347 xShapes->remove( xShape );
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */