android: Update app-specific/MIME type icons
[LibreOffice.git] / slideshow / source / engine / shapes / shapeimporter.cxx
blob92162eeb60ad085986483c4964b78bcc3ade71a8
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <utility>
21 #include <vcl/GraphicObject.hxx>
22 #include <basegfx/point/b2dpoint.hxx>
23 #include <basegfx/polygon/b2dpolygon.hxx>
24 #include <cppcanvas/basegfxfactory.hxx>
25 #include <cppcanvas/polypolygon.hxx>
26 #include <com/sun/star/awt/Rectangle.hpp>
27 #include <com/sun/star/drawing/ColorMode.hpp>
28 #include <com/sun/star/text/GraphicCrop.hpp>
29 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
30 #include <com/sun/star/drawing/PointSequence.hpp>
31 #include <com/sun/star/drawing/XLayerSupplier.hpp>
32 #include <com/sun/star/drawing/XLayerManager.hpp>
33 #include <com/sun/star/graphic/XGraphic.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
37 #include "drawshape.hxx"
38 #include "backgroundshape.hxx"
39 #include "mediashape.hxx"
40 #include "appletshape.hxx"
41 #include <shapeimporter.hxx>
42 #include <slideshowexceptions.hxx>
43 #include <tools.hxx>
44 #include <slideshowcontext.hxx>
45 #include <unoviewcontainer.hxx>
47 #include <memory>
49 using namespace com::sun::star;
51 namespace slideshow::internal {
53 namespace {
55 std::unique_ptr<GraphicObject> importShapeGraphic(uno::Reference<beans::XPropertySet> const& xPropSet)
57 std::unique_ptr<GraphicObject> xRet;
59 uno::Reference<graphic::XGraphic> xGraphic;
60 if (!getPropertyValue(xGraphic, xPropSet, "Graphic") || !xGraphic.is())
62 // no or empty property - cannot import shape graphic
63 return xRet;
66 Graphic aGraphic(xGraphic);
67 xRet.reset(new GraphicObject(std::move(aGraphic)));
69 if (GraphicType::Default == xRet->GetType() || GraphicType::NONE == xRet->GetType())
71 xRet.reset();
73 return xRet;
76 /** This shape implementation just acts as a dummy for the layermanager.
77 Its sole role is for hit test detection of group shapes.
79 class ShapeOfGroup : public Shape
81 public:
82 ShapeOfGroup( ShapeSharedPtr const& pGroupShape,
83 uno::Reference<drawing::XShape> xShape,
84 uno::Reference<beans::XPropertySet> const& xPropSet,
85 double nPrio );
87 // Shape:
88 virtual uno::Reference<drawing::XShape> getXShape() const override;
89 virtual void addViewLayer( ViewLayerSharedPtr const& pNewLayer,
90 bool bRedrawLayer ) override;
91 virtual bool removeViewLayer( ViewLayerSharedPtr const& pNewLayer ) override;
92 virtual void clearAllViewLayers() override;
93 virtual bool update() const override;
94 virtual bool render() const override;
95 virtual bool isContentChanged() const override;
96 virtual basegfx::B2DRectangle getBounds() const override;
97 virtual basegfx::B2DRectangle getDomBounds() const override;
98 virtual basegfx::B2DRectangle getUpdateArea() const override;
99 virtual bool isVisible() const override;
100 virtual double getPriority() const override;
101 virtual bool isBackgroundDetached() const override;
103 private:
104 ShapeSharedPtr const mpGroupShape;
105 uno::Reference<drawing::XShape> const mxShape;
106 double const mnPrio;
107 basegfx::B2DPoint maPosOffset;
108 double mnWidth;
109 double mnHeight;
112 ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr const& pGroupShape,
113 uno::Reference<drawing::XShape> xShape,
114 uno::Reference<beans::XPropertySet> const& xPropSet,
115 double nPrio ) :
116 mpGroupShape(pGroupShape),
117 mxShape(std::move(xShape)),
118 mnPrio(nPrio)
120 // read bound rect
121 uno::Any const aTmpRect_( xPropSet->getPropertyValue( "BoundRect" ));
122 awt::Rectangle const aTmpRect( aTmpRect_.get<awt::Rectangle>() );
123 basegfx::B2DRectangle const groupPosSize( pGroupShape->getBounds() );
124 maPosOffset = basegfx::B2DPoint( aTmpRect.X - groupPosSize.getMinX(),
125 aTmpRect.Y - groupPosSize.getMinY() );
126 mnWidth = aTmpRect.Width;
127 mnHeight = aTmpRect.Height;
130 uno::Reference<drawing::XShape> ShapeOfGroup::getXShape() const
132 return mxShape;
135 void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/,
136 bool /*bRedrawLayer*/ )
140 bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr const& /*pNewLayer*/ )
142 return true;
145 void ShapeOfGroup::clearAllViewLayers()
149 bool ShapeOfGroup::update() const
151 return true;
154 bool ShapeOfGroup::render() const
156 return true;
159 bool ShapeOfGroup::isContentChanged() const
161 return false;
164 basegfx::B2DRectangle ShapeOfGroup::getBounds() const
166 basegfx::B2DRectangle const groupPosSize( mpGroupShape->getBounds() );
167 double const posX = groupPosSize.getMinX() + maPosOffset.getX();
168 double const posY = groupPosSize.getMinY() + maPosOffset.getY();
169 return basegfx::B2DRectangle( posX, posY, posX + mnWidth, posY + mnHeight );
172 basegfx::B2DRectangle ShapeOfGroup::getDomBounds() const
174 return getBounds();
177 basegfx::B2DRectangle ShapeOfGroup::getUpdateArea() const
179 return getBounds();
182 bool ShapeOfGroup::isVisible() const
184 return mpGroupShape->isVisible();
187 double ShapeOfGroup::getPriority() const
189 return mnPrio;
192 bool ShapeOfGroup::isBackgroundDetached() const
194 return false;
197 } // anon namespace
199 ShapeSharedPtr ShapeImporter::createShape(
200 uno::Reference<drawing::XShape> const& xCurrShape,
201 uno::Reference<beans::XPropertySet> const& xPropSet,
202 std::u16string_view shapeType ) const
204 if( shapeType == u"com.sun.star.drawing.MediaShape" || shapeType == u"com.sun.star.presentation.MediaShape" )
206 // Media shape (video etc.). This is a special object
207 return createMediaShape(xCurrShape,
208 mnAscendingPrio,
209 mrContext);
211 else if( shapeType == u"com.sun.star.drawing.AppletShape" )
213 // PropertyValues to copy from XShape to applet
214 static const char* aPropertyValues[] =
216 "AppletCodeBase",
217 "AppletName",
218 "AppletCode",
219 "AppletCommands",
220 "AppletIsScript"
223 // (Java)Applet shape. This is a special object
224 return createAppletShape( xCurrShape,
225 mnAscendingPrio,
226 "com.sun.star.comp.sfx2.AppletObject",
227 aPropertyValues,
228 SAL_N_ELEMENTS(aPropertyValues),
229 mrContext );
231 else if( shapeType == u"com.sun.star.drawing.OLE2Shape" || shapeType == u"com.sun.star.presentation.OLE2Shape" )
233 // #i46224# Mark OLE shapes as foreign content - scan them for
234 // unsupported actions, and fallback to bitmap, if necessary
235 return DrawShape::create( xCurrShape,
236 mxPage,
237 mnAscendingPrio,
238 true,
239 mrContext );
241 else if( shapeType == u"com.sun.star.drawing.GraphicObjectShape" || shapeType == u"com.sun.star.presentation.GraphicObjectShape" )
243 // to get hold of GIF animations, inspect Graphic
244 // objects more thoroughly (the plain-jane shape
245 // metafile of course would only contain the first
246 // animation frame)
247 std::unique_ptr<GraphicObject> xGraphicObject(importShapeGraphic(xPropSet));
248 if (!xGraphicObject)
249 return ShapeSharedPtr(); // error loading graphic -
250 // no placeholders in
251 // slideshow
253 if (!xGraphicObject->IsAnimated())
255 // no animation - simply utilize plain draw shape import
257 // import shape as bitmap - either it's a bitmap
258 // anyway, or it's a metafile, which currently the
259 // metafile renderer might not display correctly.
260 return DrawShape::create( xCurrShape,
261 mxPage,
262 mnAscendingPrio,
263 true,
264 mrContext );
268 // now extract relevant shape attributes via API
271 drawing::ColorMode eColorMode( drawing::ColorMode_STANDARD );
272 sal_Int16 nLuminance(0);
273 sal_Int16 nContrast(0);
274 sal_Int16 nRed(0);
275 sal_Int16 nGreen(0);
276 sal_Int16 nBlue(0);
277 double nGamma(1.0);
278 sal_Int16 nTransparency(0);
279 sal_Int32 nRotation(0);
281 getPropertyValue( eColorMode, xPropSet, "GraphicColorMode" );
282 getPropertyValue( nLuminance, xPropSet, "AdjustLuminance" );
283 getPropertyValue( nContrast, xPropSet, "AdjustContrast" );
284 getPropertyValue( nRed, xPropSet, "AdjustRed" );
285 getPropertyValue( nGreen, xPropSet, "AdjustGreen" );
286 getPropertyValue( nBlue, xPropSet, "AdjustBlue" );
287 getPropertyValue( nGamma, xPropSet, "Gamma" );
288 getPropertyValue( nTransparency, xPropSet, "Transparency" );
289 getPropertyValue( nRotation, xPropSet, "RotateAngle" );
291 GraphicAttr aGraphAttrs;
292 aGraphAttrs.SetDrawMode( static_cast<GraphicDrawMode>(eColorMode) );
293 aGraphAttrs.SetLuminance( nLuminance );
294 aGraphAttrs.SetContrast( nContrast );
295 aGraphAttrs.SetChannelR( nRed );
296 aGraphAttrs.SetChannelG( nGreen );
297 aGraphAttrs.SetChannelB( nBlue );
298 aGraphAttrs.SetGamma( nGamma );
299 aGraphAttrs.SetAlpha( 255 - static_cast<sal_uInt8>(nTransparency) );
300 aGraphAttrs.SetRotation( Degree10(static_cast<sal_Int16>(nRotation*10)) );
302 text::GraphicCrop aGraphCrop;
303 if( getPropertyValue( aGraphCrop, xPropSet, "GraphicCrop" ))
305 aGraphAttrs.SetCrop( aGraphCrop.Left,
306 aGraphCrop.Top,
307 aGraphCrop.Right,
308 aGraphCrop.Bottom );
311 // fetch readily transformed and color-modified
312 // graphic
315 Graphic aGraphic(
316 xGraphicObject->GetTransformedGraphic(
317 xGraphicObject->GetPrefSize(),
318 xGraphicObject->GetPrefMapMode(),
319 aGraphAttrs ) );
321 return DrawShape::create( xCurrShape,
322 mxPage,
323 mnAscendingPrio,
324 aGraphic,
325 mrContext );
327 else
329 return DrawShape::create( xCurrShape,
330 mxPage,
331 mnAscendingPrio,
332 false,
333 mrContext );
337 bool ShapeImporter::isSkip(
338 uno::Reference<beans::XPropertySet> const& xPropSet,
339 std::u16string_view shapeType,
340 uno::Reference< drawing::XLayer> const& xLayer )
342 // skip empty presentation objects:
343 bool bEmpty = false;
344 if( getPropertyValue( bEmpty,
345 xPropSet,
346 "IsEmptyPresentationObject") &&
347 bEmpty )
349 return true;
352 //skip shapes which corresponds to annotations
353 if(xLayer.is())
355 OUString layerName;
356 const uno::Any& a(xLayer->getPropertyValue("Name") );
357 bool const bRet = (a >>= layerName);
358 if(bRet)
360 if( layerName == "DrawnInSlideshow" )
362 //Transform shapes into PolyPolygons
363 importPolygons(xPropSet);
365 return true;
370 // don't export presentation placeholders on masterpage
371 // they can be non empty when user edits the default texts
372 if(mbConvertingMasterPage)
374 if( shapeType == u"com.sun.star.presentation.TitleTextShape" || shapeType == u"com.sun.star.presentation.OutlinerShape" )
376 return true;
379 return false;
383 void ShapeImporter::importPolygons(uno::Reference<beans::XPropertySet> const& xPropSet) {
385 drawing::PointSequenceSequence aRetval;
386 sal_Int32 nLineColor=0;
387 double fLineWidth;
388 getPropertyValue( aRetval, xPropSet, "PolyPolygon" );
389 getPropertyValue( nLineColor, xPropSet, "LineColor" );
390 getPropertyValue( fLineWidth, xPropSet, "LineWidth" );
392 const drawing::PointSequence* pOuterSequence = aRetval.getArray();
394 ::basegfx::B2DPolygon aPoly;
395 basegfx::B2DPoint aPoint;
396 for( const awt::Point& rPoint : *pOuterSequence )
398 aPoint.setX(rPoint.X);
399 aPoint.setY(rPoint.Y);
400 aPoly.append( aPoint );
402 for( const auto& pView : mrContext.mrViewContainer )
404 ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
405 ::cppcanvas::BaseGfxFactory::createPolyPolygon( pView->getCanvas(),
406 aPoly ) );
407 if( pPolyPoly )
409 pPolyPoly->setRGBALineColor( unoColor2RGBColor( nLineColor ).getIntegerColor() );
410 pPolyPoly->setStrokeWidth(fLineWidth);
411 pPolyPoly->draw();
412 maPolygons.push_back(pPolyPoly);
417 ShapeSharedPtr ShapeImporter::importBackgroundShape() // throw (ShapeLoadFailedException)
419 if( maShapesStack.empty() )
420 throw ShapeLoadFailedException();
422 XShapesEntry& rTop = maShapesStack.top();
423 ShapeSharedPtr pBgShape(
424 createBackgroundShape(mxPage,
425 uno::Reference<drawing::XDrawPage>(
426 rTop.mxShapes,
427 uno::UNO_QUERY_THROW),
428 mrContext) );
429 mnAscendingPrio += 1.0;
431 return pBgShape;
434 ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException)
436 ShapeSharedPtr pRet;
437 bool bIsGroupShape = false;
439 while( !maShapesStack.empty() && !pRet )
441 XShapesEntry& rTop = maShapesStack.top();
442 if( rTop.mnPos < rTop.mnCount )
444 uno::Reference<drawing::XShape> const xCurrShape(
445 rTop.mxShapes->getByIndex( rTop.mnPos ), uno::UNO_QUERY );
446 ++rTop.mnPos;
447 uno::Reference<beans::XPropertySet> xPropSet(
448 xCurrShape, uno::UNO_QUERY );
449 if( !xPropSet.is() )
451 // we definitely need the properties of
452 // the shape here. This will also fail,
453 // if getByIndex did not return a valid
454 // shape
455 throw ShapeLoadFailedException();
458 //Retrieve the layer for the current shape
459 uno::Reference< drawing::XLayer > xDrawnInSlideshow;
461 uno::Reference< drawing::XLayerSupplier > xLayerSupplier(mxPagesSupplier, uno::UNO_QUERY);
462 if(xLayerSupplier.is())
464 uno::Reference< container::XNameAccess > xNameAccess = xLayerSupplier->getLayerManager();
466 uno::Reference< drawing::XLayerManager > xLayerManager(xNameAccess, uno::UNO_QUERY);
468 xDrawnInSlideshow = xLayerManager->getLayerForShape(xCurrShape);
471 OUString const shapeType( xCurrShape->getShapeType());
473 // is this shape presentation-invisible?
474 if( !isSkip(xPropSet, shapeType, xDrawnInSlideshow) )
476 bIsGroupShape = shapeType == "com.sun.star.drawing.GroupShape";
478 if( rTop.mpGroupShape ) // in group particle mode?
480 pRet = std::make_shared<ShapeOfGroup>(
481 rTop.mpGroupShape /* container shape */,
482 xCurrShape, xPropSet,
483 mnAscendingPrio );
485 else
487 pRet = createShape( xCurrShape, xPropSet, shapeType );
489 mnAscendingPrio += 1.0;
492 if( rTop.mnPos >= rTop.mnCount )
494 // group or top-level shapes finished:
495 maShapesStack.pop();
497 if( bIsGroupShape && pRet )
499 // push new group on the stack: group traversal
500 maShapesStack.push( XShapesEntry( pRet ) );
504 return pRet;
507 bool ShapeImporter::isImportDone() const
509 return maShapesStack.empty();
512 const PolyPolygonVector& ShapeImporter::getPolygons() const
514 return maPolygons;
517 ShapeImporter::ShapeImporter( uno::Reference<drawing::XDrawPage> const& xPage,
518 uno::Reference<drawing::XDrawPage> xActualPage,
519 uno::Reference<drawing::XDrawPagesSupplier> xPagesSupplier,
520 const SlideShowContext& rContext,
521 sal_Int32 nOrdNumStart,
522 bool bConvertingMasterPage ) :
523 mxPage(std::move( xActualPage )),
524 mxPagesSupplier(std::move( xPagesSupplier )),
525 mrContext( rContext ),
526 maPolygons(),
527 maShapesStack(),
528 mnAscendingPrio( nOrdNumStart ),
529 mbConvertingMasterPage( bConvertingMasterPage )
531 uno::Reference<drawing::XShapes> const xShapes(
532 xPage, uno::UNO_QUERY_THROW );
533 maShapesStack.push( XShapesEntry(xShapes) );
536 } // namespace presentation
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */