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 ::rtl
;
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::awt
;
37 using namespace ::com::sun::star::drawing
;
38 using namespace ::com::sun::star::graphic
;
39 using namespace ::com::sun::star::frame
;
40 using namespace ::com::sun::star::beans
;
41 using namespace ::com::sun::star::presentation
;
43 const DeviceInfo
& GraphicCollector::GetDeviceInfo( const Reference
< XComponentContext
>& rxFact
)
45 static DeviceInfo aDeviceInfo
;
46 if( !aDeviceInfo
.Width
)
50 Reference
< XDesktop2
> xDesktop
= Desktop::create( rxFact
);
51 Reference
< XFrame
> xFrame( xDesktop
->getActiveFrame() );
52 Reference
< XWindow
> xWindow( xFrame
->getContainerWindow() );
53 Reference
< XDevice
> xDevice( xWindow
, UNO_QUERY_THROW
);
54 aDeviceInfo
= xDevice
->getInfo();
63 void ImpAddEntity( std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const GraphicCollector::GraphicUser
& rUser
)
65 const OUString
aGraphicURL( rUser
.maGraphicURL
);
66 const OUString
sPackageURL( "vnd.sun.star.GraphicObject:" );
68 if ( rGraphicSettings
.mbEmbedLinkedGraphics
|| (aGraphicURL
.isEmpty() || aGraphicURL
.match( sPackageURL
, 0 ) ) )
70 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aIter( rGraphicEntities
.begin() );
71 while( aIter
!= rGraphicEntities
.end() )
73 if ( aIter
->maUser
[ 0 ].maGraphicURL
== aGraphicURL
)
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
);
84 if ( aIter
== rGraphicEntities
.end() )
86 GraphicCollector::GraphicEntity
aEntity( rUser
);
87 rGraphicEntities
.push_back( aEntity
);
92 void ImpAddGraphicEntity( const Reference
< XComponentContext
>& rxMSF
, Reference
< XShape
>& rxShape
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
94 Reference
< XGraphic
> xGraphic
;
95 Reference
< XPropertySet
> xShapePropertySet( rxShape
, UNO_QUERY_THROW
);
96 if ( xShapePropertySet
->getPropertyValue( TKGet( TK_Graphic
) ) >>= xGraphic
)
98 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
100 GraphicCollector::GraphicUser aUser
;
101 aUser
.mxShape
= rxShape
;
102 aUser
.mbFillBitmap
= sal_False
;
103 xShapePropertySet
->getPropertyValue( TKGet( TK_GraphicURL
) ) >>= aUser
.maGraphicURL
;
104 xShapePropertySet
->getPropertyValue( TKGet( TK_GraphicStreamURL
) ) >>= aUser
.maGraphicStreamURL
;
105 xShapePropertySet
->getPropertyValue( TKGet( TK_GraphicCrop
) ) >>= aGraphicCropLogic
;
106 awt::Size
aLogicalSize( rxShape
->getSize() );
108 // calculating the logical size, as if there were no cropping
109 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Bottom
)
111 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
112 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
114 awt::Size
aCropSize( aSize100thMM
.Width
- ( aGraphicCropLogic
.Left
+ aGraphicCropLogic
.Right
),
115 aSize100thMM
.Height
- ( aGraphicCropLogic
.Top
+ aGraphicCropLogic
.Bottom
));
116 if ( aCropSize
.Width
&& aCropSize
.Height
)
118 awt::Size
aNewLogSize( static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Width
* aLogicalSize
.Width
) / aCropSize
.Width
),
119 static_cast< sal_Int32
>( static_cast< double >( aSize100thMM
.Height
* aLogicalSize
.Height
) / aCropSize
.Height
) );
120 aLogicalSize
= aNewLogSize
;
124 aUser
.maGraphicCropLogic
= aGraphicCropLogic
;
125 aUser
.maLogicalSize
= aLogicalSize
;
126 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
130 void ImpAddFillBitmapEntity( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XPropertySet
>& rxPropertySet
, const awt::Size
& rLogicalSize
,
131 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
, const GraphicSettings
& rGraphicSettings
, const Reference
< XPropertySet
>& rxPagePropertySet
)
135 FillStyle eFillStyle
;
136 if ( rxPropertySet
->getPropertyValue( TKGet( TK_FillStyle
) ) >>= eFillStyle
)
138 if ( eFillStyle
== FillStyle_BITMAP
)
140 Reference
< XBitmap
> xFillBitmap
;
141 if ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmap
) ) >>= xFillBitmap
)
143 Reference
< XGraphic
> xGraphic( xFillBitmap
, UNO_QUERY_THROW
);
146 awt::Size
aLogicalSize( rLogicalSize
);
147 Reference
< XPropertySetInfo
> axPropSetInfo( rxPropertySet
->getPropertySetInfo() );
148 if ( axPropSetInfo
.is() )
150 if ( axPropSetInfo
->hasPropertyByName( TKGet( TK_FillBitmapMode
) ) )
152 BitmapMode eBitmapMode
;
153 if ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapMode
) ) >>= eBitmapMode
)
155 if ( ( eBitmapMode
== BitmapMode_REPEAT
) || ( eBitmapMode
== BitmapMode_NO_REPEAT
) )
157 sal_Bool bLogicalSize
= sal_False
;
158 awt::Size
aSize( 0, 0 );
159 if ( ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapLogicalSize
) ) >>= bLogicalSize
)
160 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeX
) ) >>= aSize
.Width
)
161 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeY
) ) >>= aSize
.Height
) )
165 if ( !aSize
.Width
|| !aSize
.Height
)
167 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
168 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
169 aLogicalSize
= aSize100thMM
;
172 aLogicalSize
= aSize
;
176 aLogicalSize
.Width
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Width
) * aSize
.Width
) / -100.0 );
177 aLogicalSize
.Height
= sal::static_int_cast
< sal_Int32
>( ( static_cast< double >( aLogicalSize
.Height
) * aSize
.Height
) / -100.0 );
184 GraphicCollector::GraphicUser aUser
;
185 aUser
.mxPropertySet
= rxPropertySet
;
186 rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapURL
) ) >>= aUser
.maGraphicURL
;
187 aUser
.mbFillBitmap
= sal_True
;
188 aUser
.maLogicalSize
= aLogicalSize
;
189 aUser
.mxPagePropertySet
= rxPagePropertySet
;
190 ImpAddEntity( rGraphicEntities
, rGraphicSettings
, aUser
);
201 void ImpCollectBackgroundGraphic( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XDrawPage
>& rxDrawPage
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
205 awt::Size
aLogicalSize( 28000, 21000 );
206 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
207 xPropertySet
->getPropertyValue( TKGet( TK_Width
) ) >>= aLogicalSize
.Width
;
208 xPropertySet
->getPropertyValue( TKGet( TK_Height
) ) >>= aLogicalSize
.Height
;
210 Reference
< XPropertySet
> xBackgroundPropSet
;
211 if ( xPropertySet
->getPropertyValue( TKGet( TK_Background
) ) >>= xBackgroundPropSet
)
212 ImpAddFillBitmapEntity( rxMSF
, xBackgroundPropSet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xPropertySet
);
219 void ImpCollectGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicEntities
)
221 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
225 const OUString
sGraphicObjectShape( "com.sun.star.drawing.GraphicObjectShape" );
226 const OUString
sGroupShape( "com.sun.star.drawing.GroupShape" );
227 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
228 const OUString
sShapeType( xShape
->getShapeType() );
229 if ( sShapeType
== sGroupShape
)
231 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
232 ImpCollectGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rGraphicEntities
);
236 if ( sShapeType
== sGraphicObjectShape
)
237 ImpAddGraphicEntity( rxMSF
, xShape
, rGraphicSettings
, rGraphicEntities
);
239 // now check for a fillstyle
240 Reference
< XPropertySet
> xEmptyPagePropSet
;
241 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
242 awt::Size
aLogicalSize( xShape
->getSize() );
243 ImpAddFillBitmapEntity( rxMSF
, xShapePropertySet
, aLogicalSize
, rGraphicEntities
, rGraphicSettings
, xEmptyPagePropSet
);
251 awt::Size
GraphicCollector::GetOriginalSize( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XGraphic
>& rxGraphic
)
253 awt::Size
aSize100thMM( 0, 0 );
254 Reference
< XPropertySet
> xGraphicPropertySet( rxGraphic
, UNO_QUERY_THROW
);
255 if ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Size100thMM
) ) >>= aSize100thMM
)
257 if ( !aSize100thMM
.Width
&& !aSize100thMM
.Height
)
258 { // MAPMODE_PIXEL USED :-(
259 awt::Size
aSourceSizePixel( 0, 0 );
260 if ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_SizePixel
) ) >>= aSourceSizePixel
)
262 const DeviceInfo
& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF
) );
263 if ( rDeviceInfo
.PixelPerMeterX
&& rDeviceInfo
.PixelPerMeterY
)
265 aSize100thMM
.Width
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Width
* 100000.0 ) / rDeviceInfo
.PixelPerMeterX
);
266 aSize100thMM
.Height
= static_cast< sal_Int32
>( ( aSourceSizePixel
.Height
* 100000.0 ) / rDeviceInfo
.PixelPerMeterY
);
274 void GraphicCollector::CollectGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
275 const GraphicSettings
& rGraphicSettings
, std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
280 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
281 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
282 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
284 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
285 ImpCollectBackgroundGraphic( rxMSF
, xDrawPage
, rGraphicSettings
, rGraphicList
);
286 Reference
< XShapes
> xDrawShapes( xDrawPage
, UNO_QUERY_THROW
);
287 ImpCollectGraphicObjects( rxMSF
, xDrawShapes
, rGraphicSettings
, rGraphicList
);
289 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
290 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
291 ImpCollectBackgroundGraphic( rxMSF
, xNotesPage
, rGraphicSettings
, rGraphicList
);
292 Reference
< XShapes
> xNotesShapes( xNotesPage
, UNO_QUERY_THROW
);
293 ImpCollectGraphicObjects( rxMSF
, xNotesShapes
, rGraphicSettings
, rGraphicList
);
295 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
296 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
297 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
299 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
300 ImpCollectBackgroundGraphic( rxMSF
, xMasterPage
, rGraphicSettings
, rGraphicList
);
301 Reference
< XShapes
> xMasterPageShapes( xMasterPage
, UNO_QUERY_THROW
);
302 ImpCollectGraphicObjects( rxMSF
, xMasterPageShapes
, rGraphicSettings
, rGraphicList
);
305 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIter( rGraphicList
.begin() );
306 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIEnd( rGraphicList
.end() );
307 while( aGraphicIter
!= aGraphicIEnd
)
309 // check if it is possible to remove the crop area
310 aGraphicIter
->mbRemoveCropArea
= rGraphicSettings
.mbRemoveCropArea
;
311 if ( aGraphicIter
->mbRemoveCropArea
)
313 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGUIter( aGraphicIter
->maUser
.begin() );
314 while( aGraphicIter
->mbRemoveCropArea
&& ( aGUIter
!= aGraphicIter
->maUser
.end() ) )
316 if ( aGUIter
->maGraphicCropLogic
.Left
|| aGUIter
->maGraphicCropLogic
.Top
317 || aGUIter
->maGraphicCropLogic
.Right
|| aGUIter
->maGraphicCropLogic
.Bottom
)
319 if ( aGUIter
== aGraphicIter
->maUser
.begin() )
320 aGraphicIter
->maGraphicCropLogic
= aGUIter
->maGraphicCropLogic
;
321 else if ( ( aGraphicIter
->maGraphicCropLogic
.Left
!= aGUIter
->maGraphicCropLogic
.Left
)
322 || ( aGraphicIter
->maGraphicCropLogic
.Top
!= aGUIter
->maGraphicCropLogic
.Top
)
323 || ( aGraphicIter
->maGraphicCropLogic
.Right
!= aGUIter
->maGraphicCropLogic
.Right
)
324 || ( aGraphicIter
->maGraphicCropLogic
.Bottom
!= aGUIter
->maGraphicCropLogic
.Bottom
) )
326 aGraphicIter
->mbRemoveCropArea
= sal_False
;
330 aGraphicIter
->mbRemoveCropArea
= sal_False
;
334 if ( !aGraphicIter
->mbRemoveCropArea
)
335 aGraphicIter
->maGraphicCropLogic
= text::GraphicCrop( 0, 0, 0, 0 );
344 void ImpCountGraphicObjects( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XShapes
>& rxShapes
, const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
346 for ( sal_Int32 i
= 0; i
< rxShapes
->getCount(); i
++ )
350 const OUString
sGraphicObjectShape( "com.sun.star.drawing.GraphicObjectShape" );
351 const OUString
sGroupShape( "com.sun.star.drawing.GroupShape" );
352 Reference
< XShape
> xShape( rxShapes
->getByIndex( i
), UNO_QUERY_THROW
);
353 const OUString
sShapeType( xShape
->getShapeType() );
354 if ( sShapeType
== sGroupShape
)
356 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY_THROW
);
357 ImpCountGraphicObjects( rxMSF
, xShapes
, rGraphicSettings
, rnGraphics
);
361 if ( sShapeType
== sGraphicObjectShape
)
366 // now check for a fillstyle
367 Reference
< XPropertySet
> xEmptyPagePropSet
;
368 Reference
< XPropertySet
> xShapePropertySet( xShape
, UNO_QUERY_THROW
);
369 FillStyle eFillStyle
;
370 if ( xShapePropertySet
->getPropertyValue( TKGet( TK_FillStyle
) ) >>= eFillStyle
)
372 if ( eFillStyle
== FillStyle_BITMAP
)
384 void ImpCountBackgroundGraphic(
385 const Reference
< XDrawPage
>& rxDrawPage
, sal_Int32
& rnGraphics
)
389 awt::Size
aLogicalSize( 28000, 21000 );
390 Reference
< XPropertySet
> xPropertySet( rxDrawPage
, UNO_QUERY_THROW
);
391 xPropertySet
->getPropertyValue( TKGet( TK_Width
) ) >>= aLogicalSize
.Width
;
392 xPropertySet
->getPropertyValue( TKGet( TK_Height
) ) >>= aLogicalSize
.Height
;
394 Reference
< XPropertySet
> xBackgroundPropSet
;
395 if ( xPropertySet
->getPropertyValue( TKGet( TK_Background
) ) >>= xBackgroundPropSet
)
397 FillStyle eFillStyle
;
398 if ( xBackgroundPropSet
->getPropertyValue( TKGet( TK_FillStyle
) ) >>= eFillStyle
)
400 if ( eFillStyle
== FillStyle_BITMAP
)
412 void GraphicCollector::CountGraphics( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
,
413 const GraphicSettings
& rGraphicSettings
, sal_Int32
& rnGraphics
)
418 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
419 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
420 for ( i
= 0; i
< xDrawPages
->getCount(); i
++ )
422 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
423 ImpCountBackgroundGraphic( xDrawPage
, rnGraphics
);
424 Reference
< XShapes
> xDrawShapes( xDrawPage
, UNO_QUERY_THROW
);
425 ImpCountGraphicObjects( rxMSF
, xDrawShapes
, rGraphicSettings
, rnGraphics
);
427 Reference
< XPresentationPage
> xPresentationPage( xDrawPage
, UNO_QUERY_THROW
);
428 Reference
< XDrawPage
> xNotesPage( xPresentationPage
->getNotesPage() );
429 ImpCountBackgroundGraphic( xNotesPage
, rnGraphics
);
430 Reference
< XShapes
> xNotesShapes( xNotesPage
, UNO_QUERY_THROW
);
431 ImpCountGraphicObjects( rxMSF
, xNotesShapes
, rGraphicSettings
, rnGraphics
);
433 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
434 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
435 for ( i
= 0; i
< xMasterPages
->getCount(); i
++ )
437 Reference
< XDrawPage
> xMasterPage( xMasterPages
->getByIndex( i
), UNO_QUERY_THROW
);
438 ImpCountBackgroundGraphic( xMasterPage
, rnGraphics
);
439 Reference
< XShapes
> xMasterPageShapes( xMasterPage
, UNO_QUERY_THROW
);
440 ImpCountGraphicObjects( rxMSF
, xMasterPageShapes
, rGraphicSettings
, rnGraphics
);
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */