1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "graphiccollector.hxx"
22 #include <com/sun/star/awt/XDevice.hpp>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/drawing/FillStyle.hpp>
25 #include <com/sun/star/drawing/BitmapMode.hpp>
26 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
27 #include <com/sun/star/presentation/XPresentationPage.hpp>
28 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
30 using namespace ::com::sun::star
;
31 using namespace ::com::sun::star::uno
;
32 using namespace ::com::sun::star::awt
;
33 using namespace ::com::sun::star::drawing
;
34 using namespace ::com::sun::star::graphic
;
35 using namespace ::com::sun::star::frame
;
36 using namespace ::com::sun::star::beans
;
37 using namespace ::com::sun::star::presentation
;
39 const DeviceInfo
& GraphicCollector::GetDeviceInfo( const Reference
< XComponentContext
>& rxFact
)
41 static DeviceInfo aDeviceInfo
;
42 if( !aDeviceInfo
.Width
)
46 Reference
< XDesktop2
> xDesktop
= Desktop::create( rxFact
);
47 Reference
< XFrame
> xFrame( xDesktop
->getActiveFrame() );
48 Reference
< XWindow
> xWindow( xFrame
->getContainerWindow() );
49 Reference
< XDevice
> xDevice( xWindow
, UNO_QUERY_THROW
);
50 aDeviceInfo
= xDevice
->getInfo();
59 static void ImpAddEntity( std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const GraphicCollector::GraphicUser
& rUser
)
61 if ( !rGraphicSettings
.mbEmbedLinkedGraphics
)
64 auto aIter
= std::find_if(rGraphicEntities
.begin(), rGraphicEntities
.end(),
65 [&rUser
](const GraphicCollector::GraphicEntity
& rGraphicEntity
) {
66 return rGraphicEntity
.maUser
[ 0 ].mxGraphic
== rUser
.mxGraphic
;
68 if ( aIter
== rGraphicEntities
.end() )
70 GraphicCollector::GraphicEntity
aEntity( rUser
);
71 rGraphicEntities
.push_back( aEntity
);
75 if ( rUser
.maLogicalSize
.Width
> aIter
->maLogicalSize
.Width
)
76 aIter
->maLogicalSize
.Width
= rUser
.maLogicalSize
.Width
;
77 if ( rUser
.maLogicalSize
.Height
> aIter
->maLogicalSize
.Height
)
78 aIter
->maLogicalSize
.Height
= rUser
.maLogicalSize
.Height
;
79 aIter
->maUser
.push_back( rUser
);
83 static void ImpAddGraphicEntity( const Reference
< XComponentContext
>& rxMSF
, Reference
< XShape
> const & rxShape
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
85 Reference
< XGraphic
> xGraphic
;
86 Reference
< XPropertySet
> xShapePropertySet( rxShape
, UNO_QUERY_THROW
);
87 if ( !(xShapePropertySet
->getPropertyValue( u
"Graphic"_ustr
) >>= xGraphic
) )
90 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
92 GraphicCollector::GraphicUser aUser
;
93 aUser
.mxShape
= rxShape
;
94 aUser
.mbFillBitmap
= false;
95 aUser
.mxGraphic
= xGraphic
;
96 xShapePropertySet
->getPropertyValue( u
"GraphicCrop"_ustr
) >>= aGraphicCropLogic
;
97 awt::Size
aLogicalSize( rxShape
->getSize() );
99 // calculating the logical size, as if there were no cropping
100 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Bottom
)
102 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
103 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
105 awt::Size
aCropSize( aSize100thMM
.Width
- ( aGraphicCropLogic
.Left
+ aGraphicCropLogic
.Right
),
106 aSize100thMM
.Height
- ( aGraphicCropLogic
.Top
+ aGraphicCropLogic
.Bottom
));
107 if ( aCropSize
.Width
&& aCropSize
.Height
)
109 awt::Size
aNewLogSize( static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Width
* aLogicalSize
.Width
) / aCropSize
.Width
),
110 static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Height
* aLogicalSize
.Height
) / aCropSize
.Height
) );
111 aLogicalSize
= aNewLogSize
;
115 aUser
.maGraphicCropLogic
= aGraphicCropLogic
;
116 aUser
.maLogicalSize
= aLogicalSize
;
117 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
120 static void ImpAddFillBitmapEntity( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XPropertySet
>& rxPropertySet
, const awt::Size
& rLogicalSize
,
121 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const Reference
< XPropertySet
>& rxPagePropertySet
)
125 FillStyle eFillStyle
;
126 if ( rxPropertySet
->getPropertyValue( u
"FillStyle"_ustr
) >>= eFillStyle
)
128 if ( eFillStyle
== FillStyle_BITMAP
)
130 Reference
< XBitmap
> xFillBitmap
;
131 if ( rxPropertySet
->getPropertyValue( u
"FillBitmap"_ustr
) >>= xFillBitmap
)
133 Reference
< XGraphic
> xGraphic( xFillBitmap
, UNO_QUERY_THROW
);
134 awt::Size
aLogicalSize( rLogicalSize
);
135 Reference
< XPropertySetInfo
> axPropSetInfo( rxPropertySet
->getPropertySetInfo() );
136 if ( axPropSetInfo
.is() )
138 if ( axPropSetInfo
->hasPropertyByName( u
"FillBitmapMode"_ustr
) )
140 BitmapMode eBitmapMode
;
141 if ( rxPropertySet
->getPropertyValue( u
"FillBitmapMode"_ustr
) >>= eBitmapMode
)
143 if ( ( eBitmapMode
== BitmapMode_REPEAT
) || ( eBitmapMode
== BitmapMode_NO_REPEAT
) )
145 bool bLogicalSize
= false;
146 awt::Size
aSize( 0, 0 );
147 if ( ( rxPropertySet
->getPropertyValue( u
"FillBitmapLogicalSize"_ustr
) >>= bLogicalSize
)
148 && ( rxPropertySet
->getPropertyValue( u
"FillBitmapSizeX"_ustr
) >>= aSize
.Width
)
149 && ( rxPropertySet
->getPropertyValue( u
"FillBitmapSizeY"_ustr
) >>= aSize
.Height
) )
153 if ( !aSize
.Width
|| !aSize
.Height
)
155 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
156 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
157 aLogicalSize
= aSize100thMM
;
160 aLogicalSize
= aSize
;
164 aLogicalSize
.Width
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Width
) * aSize
.Width
) / -100.0 );
165 aLogicalSize
.Height
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Height
) * aSize
.Height
) / -100.0 );
172 GraphicCollector::GraphicUser aUser
;
173 aUser
.mxPropertySet
= rxPropertySet
;
174 aUser
.mxGraphic
= std::move(xGraphic
);
175 aUser
.mbFillBitmap
= true;
176 aUser
.maLogicalSize
= aLogicalSize
;
177 aUser
.mxPagePropertySet
= rxPagePropertySet
;
178 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
188 static void ImpCollectBackgroundGraphic( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XDrawPage
>& rxDrawPage
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
192 awt::Size
aLogicalSize( 28000, 21000 );
193 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
194 xPropertySet
->getPropertyValue( u
"Width"_ustr
) >>= aLogicalSize
.Width
;
195 xPropertySet
->getPropertyValue( u
"Height"_ustr
) >>= aLogicalSize
.Height
;
197 Reference
< XPropertySet
> xBackgroundPropSet
;
198 if ( xPropertySet
->getPropertyValue( u
"Background"_ustr
) >>= xBackgroundPropSet
)
199 ImpAddFillBitmapEntity( rxMSF
, xBackgroundPropSet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xPropertySet
);
206 static void ImpCollectGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
208 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
212 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
213 const OUString
sShapeType( xShape
->getShapeType() );
214 if ( sShapeType
== "com.sun.star.drawing.GroupShape" )
216 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
217 ImpCollectGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rGraphicEntities
);
221 if ( sShapeType
== "com.sun.star.drawing.GraphicObjectShape" ||
222 sShapeType
== "com.sun.star.presentation.GraphicObjectShape" )
223 ImpAddGraphicEntity( rxMSF
, xShape
, rGraphicSettings
, rGraphicEntities
);
225 // now check for a fillstyle
226 Reference
< XPropertySet
> xEmptyPagePropSet
;
227 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
228 awt::Size
aLogicalSize( xShape
->getSize() );
229 ImpAddFillBitmapEntity( rxMSF
, xShapePropertySet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xEmptyPagePropSet
);
237 awt::Size
GraphicCollector::GetOriginalSize( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XGraphic
>& rxGraphic
)
239 awt::Size
aSize100thMM( 0, 0 );
240 Reference
< XPropertySet
> xGraphicPropertySet( rxGraphic
, UNO_QUERY_THROW
);
241 if ( xGraphicPropertySet
->getPropertyValue( u
"Size100thMM"_ustr
) >>= aSize100thMM
)
243 if ( !aSize100thMM
.Width
&& !aSize100thMM
.Height
)
244 { // MAPMODE_PIXEL USED :-(
245 awt::Size
aSourceSizePixel( 0, 0 );
246 if ( xGraphicPropertySet
->getPropertyValue( u
"SizePixel"_ustr
) >>= aSourceSizePixel
)
248 const DeviceInfo
& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF
) );
249 if ( rDeviceInfo
.PixelPerMeterX
&& rDeviceInfo
.PixelPerMeterY
)
251 aSize100thMM
.Width
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Width
* 100000.0 ) / rDeviceInfo
.PixelPerMeterX
);
252 aSize100thMM
.Height
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Height
* 100000.0 ) / rDeviceInfo
.PixelPerMeterY
);
260 void GraphicCollector::CollectGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
261 const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
266 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
267 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_SET_THROW
);
268 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
270 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
271 ImpCollectBackgroundGraphic( rxMSF
, xDrawPage
, rGraphicSettings
, rGraphicList
);
272 ImpCollectGraphicObjects( rxMSF
, xDrawPage
, rGraphicSettings
, rGraphicList
);
274 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
275 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
276 ImpCollectBackgroundGraphic( rxMSF
, xNotesPage
, rGraphicSettings
, rGraphicList
);
277 ImpCollectGraphicObjects( rxMSF
, xNotesPage
, rGraphicSettings
, rGraphicList
);
279 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
280 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_SET_THROW
);
281 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
283 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
284 ImpCollectBackgroundGraphic( rxMSF
, xMasterPage
, rGraphicSettings
, rGraphicList
);
285 ImpCollectGraphicObjects( rxMSF
, xMasterPage
, rGraphicSettings
, rGraphicList
);
288 for( auto& rGraphic
: rGraphicList
)
290 // check if it is possible to remove the crop area
291 rGraphic
.mbRemoveCropArea
= rGraphicSettings
.mbRemoveCropArea
;
292 if ( rGraphic
.mbRemoveCropArea
)
294 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGUIter( rGraphic
.maUser
.begin() );
295 while( rGraphic
.mbRemoveCropArea
&& ( aGUIter
!= rGraphic
.maUser
.end() ) )
297 if ( aGUIter
->maGraphicCropLogic
.Left
|| aGUIter
->maGraphicCropLogic
.Top
298 || aGUIter
->maGraphicCropLogic
.Right
|| aGUIter
->maGraphicCropLogic
.Bottom
)
300 if ( aGUIter
== rGraphic
.maUser
.begin() )
301 rGraphic
.maGraphicCropLogic
= aGUIter
->maGraphicCropLogic
;
302 else if ( ( rGraphic
.maGraphicCropLogic
.Left
!= aGUIter
->maGraphicCropLogic
.Left
)
303 || ( rGraphic
.maGraphicCropLogic
.Top
!= aGUIter
->maGraphicCropLogic
.Top
)
304 || ( rGraphic
.maGraphicCropLogic
.Right
!= aGUIter
->maGraphicCropLogic
.Right
)
305 || ( rGraphic
.maGraphicCropLogic
.Bottom
!= aGUIter
->maGraphicCropLogic
.Bottom
) )
307 rGraphic
.mbRemoveCropArea
= false;
311 rGraphic
.mbRemoveCropArea
= false;
315 if ( !rGraphic
.mbRemoveCropArea
)
316 rGraphic
.maGraphicCropLogic
= text::GraphicCrop( 0, 0, 0, 0 );
324 static void ImpCountGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
326 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
330 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
331 const OUString
sShapeType( xShape
->getShapeType() );
332 if ( sShapeType
== "com.sun.star.drawing.GroupShape" )
334 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
335 ImpCountGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rnGraphics
);
339 if ( sShapeType
== "com.sun.star.drawing.GraphicObjectShape" ||
340 sShapeType
== "com.sun.star.presentation.GraphicObjectShape" )
345 // now check for a fillstyle
346 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
347 FillStyle eFillStyle
;
348 if ( xShapePropertySet
->getPropertyValue( u
"FillStyle"_ustr
) >>= eFillStyle
)
350 if ( eFillStyle
== FillStyle_BITMAP
)
362 static void ImpCountBackgroundGraphic(
363 const Reference
< XDrawPage
>& rxDrawPage
, sal_Int32
& rnGraphics
)
367 awt::Size
aLogicalSize( 28000, 21000 );
368 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
369 xPropertySet
->getPropertyValue( u
"Width"_ustr
) >>= aLogicalSize
.Width
;
370 xPropertySet
->getPropertyValue( u
"Height"_ustr
) >>= aLogicalSize
.Height
;
372 Reference
< XPropertySet
> xBackgroundPropSet
;
373 if ( xPropertySet
->getPropertyValue( u
"Background"_ustr
) >>= xBackgroundPropSet
)
375 FillStyle eFillStyle
;
376 if ( xBackgroundPropSet
->getPropertyValue( u
"FillStyle"_ustr
) >>= eFillStyle
)
378 if ( eFillStyle
== FillStyle_BITMAP
)
390 void GraphicCollector::CountGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
391 const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
396 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
397 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_SET_THROW
);
398 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
400 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
401 ImpCountBackgroundGraphic( xDrawPage
, rnGraphics
);
402 ImpCountGraphicObjects( rxMSF
, xDrawPage
, rGraphicSettings
, rnGraphics
);
404 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
405 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
406 ImpCountBackgroundGraphic( xNotesPage
, rnGraphics
);
407 ImpCountGraphicObjects( rxMSF
, xNotesPage
, rGraphicSettings
, rnGraphics
);
409 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
410 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_SET_THROW
);
411 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
413 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
414 ImpCountBackgroundGraphic( xMasterPage
, rnGraphics
);
415 ImpCountGraphicObjects( rxMSF
, xMasterPage
, rGraphicSettings
, rnGraphics
);
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */