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/frame/XFramesSupplier.hpp>
25 #include <com/sun/star/drawing/FillStyle.hpp>
26 #include <com/sun/star/drawing/BitmapMode.hpp>
27 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
28 #include <com/sun/star/presentation/XPresentationPage.hpp>
29 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
31 #include "impoptimizer.hxx"
33 using namespace ::com::sun::star
;
34 using namespace ::com::sun::star::uno
;
35 using namespace ::com::sun::star::awt
;
36 using namespace ::com::sun::star::drawing
;
37 using namespace ::com::sun::star::graphic
;
38 using namespace ::com::sun::star::frame
;
39 using namespace ::com::sun::star::beans
;
40 using namespace ::com::sun::star::presentation
;
42 const DeviceInfo
& GraphicCollector::GetDeviceInfo( const Reference
< XComponentContext
>& rxFact
)
44 static DeviceInfo aDeviceInfo
;
45 if( !aDeviceInfo
.Width
)
49 Reference
< XDesktop2
> xDesktop
= Desktop::create( rxFact
);
50 Reference
< XFrame
> xFrame( xDesktop
->getActiveFrame() );
51 Reference
< XWindow
> xWindow( xFrame
->getContainerWindow() );
52 Reference
< XDevice
> xDevice( xWindow
, UNO_QUERY_THROW
);
53 aDeviceInfo
= xDevice
->getInfo();
62 void ImpAddEntity( std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const GraphicCollector::GraphicUser
& rUser
)
64 const OUString
aGraphicURL( rUser
.maGraphicURL
);
65 const OUString
sPackageURL( "vnd.sun.star.GraphicObject:" );
67 if ( rGraphicSettings
.mbEmbedLinkedGraphics
|| (aGraphicURL
.isEmpty() || aGraphicURL
.match( sPackageURL
, 0 ) ) )
69 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aIter( rGraphicEntities
.begin() );
70 while( aIter
!= rGraphicEntities
.end() )
72 if ( aIter
->maUser
[ 0 ].maGraphicURL
== aGraphicURL
)
74 if ( rUser
.maLogicalSize
.Width
> aIter
->maLogicalSize
.Width
)
75 aIter
->maLogicalSize
.Width
= rUser
.maLogicalSize
.Width
;
76 if ( rUser
.maLogicalSize
.Height
> aIter
->maLogicalSize
.Height
)
77 aIter
->maLogicalSize
.Height
= rUser
.maLogicalSize
.Height
;
78 aIter
->maUser
.push_back( rUser
);
83 if ( aIter
== rGraphicEntities
.end() )
85 GraphicCollector::GraphicEntity
aEntity( rUser
);
86 rGraphicEntities
.push_back( aEntity
);
91 void ImpAddGraphicEntity( const Reference
< XComponentContext
>& rxMSF
, Reference
< XShape
>& rxShape
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
93 Reference
< XGraphic
> xGraphic
;
94 Reference
< XPropertySet
> xShapePropertySet( rxShape
, UNO_QUERY_THROW
);
95 if ( xShapePropertySet
->getPropertyValue( "Graphic" ) >>= xGraphic
)
97 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
99 GraphicCollector::GraphicUser aUser
;
100 aUser
.mxShape
= rxShape
;
101 aUser
.mbFillBitmap
= false;
102 xShapePropertySet
->getPropertyValue( "GraphicURL" ) >>= aUser
.maGraphicURL
;
103 xShapePropertySet
->getPropertyValue( "GraphicStreamURL" ) >>= aUser
.maGraphicStreamURL
;
104 xShapePropertySet
->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropLogic
;
105 awt::Size
aLogicalSize( rxShape
->getSize() );
107 // calculating the logical size, as if there were no cropping
108 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Bottom
)
110 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
111 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
113 awt::Size
aCropSize( aSize100thMM
.Width
- ( aGraphicCropLogic
.Left
+ aGraphicCropLogic
.Right
),
114 aSize100thMM
.Height
- ( aGraphicCropLogic
.Top
+ aGraphicCropLogic
.Bottom
));
115 if ( aCropSize
.Width
&& aCropSize
.Height
)
117 awt::Size
aNewLogSize( static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Width
* aLogicalSize
.Width
) / aCropSize
.Width
),
118 static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Height
* aLogicalSize
.Height
) / aCropSize
.Height
) );
119 aLogicalSize
= aNewLogSize
;
123 aUser
.maGraphicCropLogic
= aGraphicCropLogic
;
124 aUser
.maLogicalSize
= aLogicalSize
;
125 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
129 void ImpAddFillBitmapEntity( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XPropertySet
>& rxPropertySet
, const awt::Size
& rLogicalSize
,
130 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const Reference
< XPropertySet
>& rxPagePropertySet
)
134 FillStyle eFillStyle
;
135 if ( rxPropertySet
->getPropertyValue( "FillStyle" ) >>= eFillStyle
)
137 if ( eFillStyle
== FillStyle_BITMAP
)
139 Reference
< XBitmap
> xFillBitmap
;
140 if ( rxPropertySet
->getPropertyValue( "FillBitmap" ) >>= xFillBitmap
)
142 Reference
< XGraphic
> xGraphic( xFillBitmap
, UNO_QUERY_THROW
);
145 awt::Size
aLogicalSize( rLogicalSize
);
146 Reference
< XPropertySetInfo
> axPropSetInfo( rxPropertySet
->getPropertySetInfo() );
147 if ( axPropSetInfo
.is() )
149 if ( axPropSetInfo
->hasPropertyByName( "FillBitmapMode" ) )
151 BitmapMode eBitmapMode
;
152 if ( rxPropertySet
->getPropertyValue( "FillBitmapMode" ) >>= eBitmapMode
)
154 if ( ( eBitmapMode
== BitmapMode_REPEAT
) || ( eBitmapMode
== BitmapMode_NO_REPEAT
) )
156 bool bLogicalSize
= false;
157 awt::Size
aSize( 0, 0 );
158 if ( ( rxPropertySet
->getPropertyValue( "FillBitmapLogicalSize" ) >>= bLogicalSize
)
159 && ( rxPropertySet
->getPropertyValue( "FillBitmapSizeX" ) >>= aSize
.Width
)
160 && ( rxPropertySet
->getPropertyValue( "FillBitmapSizeY" ) >>= aSize
.Height
) )
164 if ( !aSize
.Width
|| !aSize
.Height
)
166 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
167 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
168 aLogicalSize
= aSize100thMM
;
171 aLogicalSize
= aSize
;
175 aLogicalSize
.Width
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Width
) * aSize
.Width
) / -100.0 );
176 aLogicalSize
.Height
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Height
) * aSize
.Height
) / -100.0 );
183 GraphicCollector::GraphicUser aUser
;
184 aUser
.mxPropertySet
= rxPropertySet
;
185 rxPropertySet
->getPropertyValue( "FillBitmapURL" ) >>= aUser
.maGraphicURL
;
186 aUser
.mbFillBitmap
= true;
187 aUser
.maLogicalSize
= aLogicalSize
;
188 aUser
.mxPagePropertySet
= rxPagePropertySet
;
189 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
200 void ImpCollectBackgroundGraphic( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XDrawPage
>& rxDrawPage
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
204 awt::Size
aLogicalSize( 28000, 21000 );
205 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
206 xPropertySet
->getPropertyValue( "Width" ) >>= aLogicalSize
.Width
;
207 xPropertySet
->getPropertyValue( "Height" ) >>= aLogicalSize
.Height
;
209 Reference
< XPropertySet
> xBackgroundPropSet
;
210 if ( xPropertySet
->getPropertyValue( "Background" ) >>= xBackgroundPropSet
)
211 ImpAddFillBitmapEntity( rxMSF
, xBackgroundPropSet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xPropertySet
);
218 void ImpCollectGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
220 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
224 const OUString
sGraphicObjectShape( "com.sun.star.drawing.GraphicObjectShape" );
225 const OUString
sGroupShape( "com.sun.star.drawing.GroupShape" );
226 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
227 const OUString
sShapeType( xShape
->getShapeType() );
228 if ( sShapeType
== sGroupShape
)
230 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
231 ImpCollectGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rGraphicEntities
);
235 if ( sShapeType
== sGraphicObjectShape
)
236 ImpAddGraphicEntity( rxMSF
, xShape
, rGraphicSettings
, rGraphicEntities
);
238 // now check for a fillstyle
239 Reference
< XPropertySet
> xEmptyPagePropSet
;
240 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
241 awt::Size
aLogicalSize( xShape
->getSize() );
242 ImpAddFillBitmapEntity( rxMSF
, xShapePropertySet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xEmptyPagePropSet
);
250 awt::Size
GraphicCollector::GetOriginalSize( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XGraphic
>& rxGraphic
)
252 awt::Size
aSize100thMM( 0, 0 );
253 Reference
< XPropertySet
> xGraphicPropertySet( rxGraphic
, UNO_QUERY_THROW
);
254 if ( xGraphicPropertySet
->getPropertyValue( "Size100thMM" ) >>= aSize100thMM
)
256 if ( !aSize100thMM
.Width
&& !aSize100thMM
.Height
)
257 { // MAPMODE_PIXEL USED :-(
258 awt::Size
aSourceSizePixel( 0, 0 );
259 if ( xGraphicPropertySet
->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel
)
261 const DeviceInfo
& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF
) );
262 if ( rDeviceInfo
.PixelPerMeterX
&& rDeviceInfo
.PixelPerMeterY
)
264 aSize100thMM
.Width
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Width
* 100000.0 ) / rDeviceInfo
.PixelPerMeterX
);
265 aSize100thMM
.Height
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Height
* 100000.0 ) / rDeviceInfo
.PixelPerMeterY
);
273 void GraphicCollector::CollectGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
274 const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
279 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
280 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
281 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
283 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
284 ImpCollectBackgroundGraphic( rxMSF
, xDrawPage
, rGraphicSettings
, rGraphicList
);
285 ImpCollectGraphicObjects( rxMSF
, xDrawPage
, rGraphicSettings
, rGraphicList
);
287 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
288 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
289 ImpCollectBackgroundGraphic( rxMSF
, xNotesPage
, rGraphicSettings
, rGraphicList
);
290 ImpCollectGraphicObjects( rxMSF
, xNotesPage
, rGraphicSettings
, rGraphicList
);
292 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
293 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
294 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
296 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
297 ImpCollectBackgroundGraphic( rxMSF
, xMasterPage
, rGraphicSettings
, rGraphicList
);
298 ImpCollectGraphicObjects( rxMSF
, xMasterPage
, rGraphicSettings
, rGraphicList
);
301 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIter( rGraphicList
.begin() );
302 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIEnd( rGraphicList
.end() );
303 while( aGraphicIter
!= aGraphicIEnd
)
305 // check if it is possible to remove the crop area
306 aGraphicIter
->mbRemoveCropArea
= rGraphicSettings
.mbRemoveCropArea
;
307 if ( aGraphicIter
->mbRemoveCropArea
)
309 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGUIter( aGraphicIter
->maUser
.begin() );
310 while( aGraphicIter
->mbRemoveCropArea
&& ( aGUIter
!= aGraphicIter
->maUser
.end() ) )
312 if ( aGUIter
->maGraphicCropLogic
.Left
|| aGUIter
->maGraphicCropLogic
.Top
313 || aGUIter
->maGraphicCropLogic
.Right
|| aGUIter
->maGraphicCropLogic
.Bottom
)
315 if ( aGUIter
== aGraphicIter
->maUser
.begin() )
316 aGraphicIter
->maGraphicCropLogic
= aGUIter
->maGraphicCropLogic
;
317 else if ( ( aGraphicIter
->maGraphicCropLogic
.Left
!= aGUIter
->maGraphicCropLogic
.Left
)
318 || ( aGraphicIter
->maGraphicCropLogic
.Top
!= aGUIter
->maGraphicCropLogic
.Top
)
319 || ( aGraphicIter
->maGraphicCropLogic
.Right
!= aGUIter
->maGraphicCropLogic
.Right
)
320 || ( aGraphicIter
->maGraphicCropLogic
.Bottom
!= aGUIter
->maGraphicCropLogic
.Bottom
) )
322 aGraphicIter
->mbRemoveCropArea
= false;
326 aGraphicIter
->mbRemoveCropArea
= false;
330 if ( !aGraphicIter
->mbRemoveCropArea
)
331 aGraphicIter
->maGraphicCropLogic
= text::GraphicCrop( 0, 0, 0, 0 );
340 void ImpCountGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
342 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
346 const OUString
sGraphicObjectShape( "com.sun.star.drawing.GraphicObjectShape" );
347 const OUString
sGroupShape( "com.sun.star.drawing.GroupShape" );
348 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
349 const OUString
sShapeType( xShape
->getShapeType() );
350 if ( sShapeType
== sGroupShape
)
352 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
353 ImpCountGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rnGraphics
);
357 if ( sShapeType
== sGraphicObjectShape
)
362 // now check for a fillstyle
363 Reference
< XPropertySet
> xEmptyPagePropSet
;
364 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
365 FillStyle eFillStyle
;
366 if ( xShapePropertySet
->getPropertyValue( "FillStyle" ) >>= eFillStyle
)
368 if ( eFillStyle
== FillStyle_BITMAP
)
380 void ImpCountBackgroundGraphic(
381 const Reference
< XDrawPage
>& rxDrawPage
, sal_Int32
& rnGraphics
)
385 awt::Size
aLogicalSize( 28000, 21000 );
386 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
387 xPropertySet
->getPropertyValue( "Width" ) >>= aLogicalSize
.Width
;
388 xPropertySet
->getPropertyValue( "Height" ) >>= aLogicalSize
.Height
;
390 Reference
< XPropertySet
> xBackgroundPropSet
;
391 if ( xPropertySet
->getPropertyValue( "Background" ) >>= xBackgroundPropSet
)
393 FillStyle eFillStyle
;
394 if ( xBackgroundPropSet
->getPropertyValue( "FillStyle" ) >>= eFillStyle
)
396 if ( eFillStyle
== FillStyle_BITMAP
)
408 void GraphicCollector::CountGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
409 const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
414 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
415 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
416 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
418 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
419 ImpCountBackgroundGraphic( xDrawPage
, rnGraphics
);
420 ImpCountGraphicObjects( rxMSF
, xDrawPage
, rGraphicSettings
, rnGraphics
);
422 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
423 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
424 ImpCountBackgroundGraphic( xNotesPage
, rnGraphics
);
425 ImpCountGraphicObjects( rxMSF
, xNotesPage
, rGraphicSettings
, rnGraphics
);
427 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
428 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
429 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
431 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
432 ImpCountBackgroundGraphic( xMasterPage
, rnGraphics
);
433 ImpCountGraphicObjects( rxMSF
, xMasterPage
, rGraphicSettings
, rnGraphics
);
441 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */