LibreOffice Module sdext (master)  1
graphiccollector.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
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>
29 
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;
38 
40 {
41  static DeviceInfo aDeviceInfo;
42  if( !aDeviceInfo.Width )
43  {
44  try
45  {
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();
51  }
52  catch( Exception& )
53  {
54  }
55  }
56  return aDeviceInfo;
57 }
58 
59 static void ImpAddEntity( std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities, const GraphicSettings& rGraphicSettings, const GraphicCollector::GraphicUser& rUser )
60 {
61  if ( !rGraphicSettings.mbEmbedLinkedGraphics )
62  return;
63 
64  auto aIter = std::find_if(rGraphicEntities.begin(), rGraphicEntities.end(),
65  [&rUser](const GraphicCollector::GraphicEntity& rGraphicEntity) {
66  return rGraphicEntity.maUser[ 0 ].mxGraphic == rUser.mxGraphic;
67  });
68  if ( aIter == rGraphicEntities.end() )
69  {
70  GraphicCollector::GraphicEntity aEntity( rUser );
71  rGraphicEntities.push_back( aEntity );
72  }
73  else
74  {
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 );
80  }
81 }
82 
83 static void ImpAddGraphicEntity( const Reference< XComponentContext >& rxMSF, Reference< XShape > const & rxShape, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
84 {
85  Reference< XGraphic > xGraphic;
86  Reference< XPropertySet > xShapePropertySet( rxShape, UNO_QUERY_THROW );
87  if ( !(xShapePropertySet->getPropertyValue( "Graphic" ) >>= xGraphic) )
88  return;
89 
90  text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 );
91 
93  aUser.mxShape = rxShape;
94  aUser.mbFillBitmap = false;
95  aUser.mxGraphic = xGraphic;
96  xShapePropertySet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropLogic;
97  awt::Size aLogicalSize( rxShape->getSize() );
98 
99  // calculating the logical size, as if there were no cropping
100  if ( aGraphicCropLogic.Left || aGraphicCropLogic.Right || aGraphicCropLogic.Top || aGraphicCropLogic.Bottom )
101  {
102  awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
103  if ( aSize100thMM.Width && aSize100thMM.Height )
104  {
105  awt::Size aCropSize( aSize100thMM.Width - ( aGraphicCropLogic.Left + aGraphicCropLogic.Right ),
106  aSize100thMM.Height - ( aGraphicCropLogic.Top + aGraphicCropLogic.Bottom ));
107  if ( aCropSize.Width && aCropSize.Height )
108  {
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;
112  }
113  }
114  }
115  aUser.maGraphicCropLogic = aGraphicCropLogic;
116  aUser.maLogicalSize = aLogicalSize;
117  ImpAddEntity( rGraphicEntities, rGraphicSettings, aUser );
118 }
119 
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 )
122 {
123  try
124  {
125  FillStyle eFillStyle;
126  if ( rxPropertySet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
127  {
128  if ( eFillStyle == FillStyle_BITMAP )
129  {
130  Reference< XBitmap > xFillBitmap;
131  if ( rxPropertySet->getPropertyValue( "FillBitmap" ) >>= xFillBitmap )
132  {
133  Reference< XGraphic > xGraphic( xFillBitmap, UNO_QUERY_THROW );
134  awt::Size aLogicalSize( rLogicalSize );
135  Reference< XPropertySetInfo > axPropSetInfo( rxPropertySet->getPropertySetInfo() );
136  if ( axPropSetInfo.is() )
137  {
138  if ( axPropSetInfo->hasPropertyByName( "FillBitmapMode" ) )
139  {
140  BitmapMode eBitmapMode;
141  if ( rxPropertySet->getPropertyValue( "FillBitmapMode" ) >>= eBitmapMode )
142  {
143  if ( ( eBitmapMode == BitmapMode_REPEAT ) || ( eBitmapMode == BitmapMode_NO_REPEAT ) )
144  {
145  bool bLogicalSize = false;
146  awt::Size aSize( 0, 0 );
147  if ( ( rxPropertySet->getPropertyValue( "FillBitmapLogicalSize" ) >>= bLogicalSize )
148  && ( rxPropertySet->getPropertyValue( "FillBitmapSizeX" ) >>= aSize.Width )
149  && ( rxPropertySet->getPropertyValue( "FillBitmapSizeY" ) >>= aSize.Height ) )
150  {
151  if ( bLogicalSize )
152  {
153  if ( !aSize.Width || !aSize.Height )
154  {
155  awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
156  if ( aSize100thMM.Width && aSize100thMM.Height )
157  aLogicalSize = aSize100thMM;
158  }
159  else
160  aLogicalSize = aSize;
161  }
162  else
163  {
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 );
166  }
167  }
168  }
169  }
170  }
171  }
173  aUser.mxPropertySet = rxPropertySet;
174  aUser.mxGraphic = xGraphic;
175  aUser.mbFillBitmap = true;
176  aUser.maLogicalSize = aLogicalSize;
177  aUser.mxPagePropertySet = rxPagePropertySet;
178  ImpAddEntity( rGraphicEntities, rGraphicSettings, aUser );
179  }
180  }
181  }
182  }
183  catch( Exception& )
184  {
185  }
186 }
187 
188 static void ImpCollectBackgroundGraphic( const Reference< XComponentContext >& rxMSF, const Reference< XDrawPage >& rxDrawPage, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
189 {
190  try
191  {
192  awt::Size aLogicalSize( 28000, 21000 );
193  Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW );
194  xPropertySet->getPropertyValue( "Width" ) >>= aLogicalSize.Width;
195  xPropertySet->getPropertyValue( "Height" ) >>= aLogicalSize.Height;
196 
197  Reference< XPropertySet > xBackgroundPropSet;
198  if ( xPropertySet->getPropertyValue( "Background" ) >>= xBackgroundPropSet )
199  ImpAddFillBitmapEntity( rxMSF, xBackgroundPropSet, aLogicalSize, rGraphicEntities, rGraphicSettings, xPropertySet );
200  }
201  catch( Exception& )
202  {
203  }
204 }
205 
206 static void ImpCollectGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
207 {
208  for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ )
209  {
210  try
211  {
212  Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW );
213  const OUString sShapeType( xShape->getShapeType() );
214  if ( sShapeType == "com.sun.star.drawing.GroupShape" )
215  {
216  Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW );
217  ImpCollectGraphicObjects( rxMSF, xShapes, rGraphicSettings, rGraphicEntities );
218  continue;
219  }
220 
221  if ( sShapeType == "com.sun.star.drawing.GraphicObjectShape" ||
222  sShapeType == "com.sun.star.presentation.GraphicObjectShape" )
223  ImpAddGraphicEntity( rxMSF, xShape, rGraphicSettings, rGraphicEntities );
224 
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 );
230  }
231  catch( Exception& )
232  {
233  }
234  }
235 }
236 
237 awt::Size GraphicCollector::GetOriginalSize( const Reference< XComponentContext >& rxMSF, const Reference< XGraphic >& rxGraphic )
238 {
239  awt::Size aSize100thMM( 0, 0 );
240  Reference< XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
241  if ( xGraphicPropertySet->getPropertyValue( "Size100thMM" ) >>= aSize100thMM )
242  {
243  if ( !aSize100thMM.Width && !aSize100thMM.Height )
244  { // MAPMODE_PIXEL USED :-(
245  awt::Size aSourceSizePixel( 0, 0 );
246  if ( xGraphicPropertySet->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel )
247  {
248  const DeviceInfo& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF ) );
249  if ( rDeviceInfo.PixelPerMeterX && rDeviceInfo.PixelPerMeterY )
250  {
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 );
253  }
254  }
255  }
256  }
257  return aSize100thMM;
258 }
259 
260 void GraphicCollector::CollectGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel,
261  const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicList )
262 {
263  try
264  {
265  sal_Int32 i;
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++ )
269  {
270  Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
271  ImpCollectBackgroundGraphic( rxMSF, xDrawPage, rGraphicSettings, rGraphicList );
272  ImpCollectGraphicObjects( rxMSF, xDrawPage, rGraphicSettings, rGraphicList );
273 
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 );
278  }
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++ )
282  {
283  Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW );
284  ImpCollectBackgroundGraphic( rxMSF, xMasterPage, rGraphicSettings, rGraphicList );
285  ImpCollectGraphicObjects( rxMSF, xMasterPage, rGraphicSettings, rGraphicList );
286  }
287 
288  for( auto& rGraphic : rGraphicList )
289  {
290  // check if it is possible to remove the crop area
291  rGraphic.mbRemoveCropArea = rGraphicSettings.mbRemoveCropArea;
292  if ( rGraphic.mbRemoveCropArea )
293  {
294  std::vector< GraphicCollector::GraphicUser >::iterator aGUIter( rGraphic.maUser.begin() );
295  while( rGraphic.mbRemoveCropArea && ( aGUIter != rGraphic.maUser.end() ) )
296  {
297  if ( aGUIter->maGraphicCropLogic.Left || aGUIter->maGraphicCropLogic.Top
298  || aGUIter->maGraphicCropLogic.Right || aGUIter->maGraphicCropLogic.Bottom )
299  {
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 ) )
306  {
307  rGraphic.mbRemoveCropArea = false;
308  }
309  }
310  else
311  rGraphic.mbRemoveCropArea = false;
312  ++aGUIter;
313  }
314  }
315  if ( !rGraphic.mbRemoveCropArea )
316  rGraphic.maGraphicCropLogic = text::GraphicCrop( 0, 0, 0, 0 );
317  }
318  }
319  catch ( Exception& )
320  {
321  }
322 }
323 
324 static void ImpCountGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics )
325 {
326  for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ )
327  {
328  try
329  {
330  Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW );
331  const OUString sShapeType( xShape->getShapeType() );
332  if ( sShapeType == "com.sun.star.drawing.GroupShape" )
333  {
334  Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW );
335  ImpCountGraphicObjects( rxMSF, xShapes, rGraphicSettings, rnGraphics );
336  continue;
337  }
338 
339  if ( sShapeType == "com.sun.star.drawing.GraphicObjectShape" ||
340  sShapeType == "com.sun.star.presentation.GraphicObjectShape" )
341  {
342  rnGraphics++;
343  }
344 
345  // now check for a fillstyle
346  Reference< XPropertySet > xShapePropertySet( xShape, UNO_QUERY_THROW );
347  FillStyle eFillStyle;
348  if ( xShapePropertySet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
349  {
350  if ( eFillStyle == FillStyle_BITMAP )
351  {
352  rnGraphics++;
353  }
354  }
355  }
356  catch( Exception& )
357  {
358  }
359  }
360 }
361 
363  const Reference< XDrawPage >& rxDrawPage, sal_Int32& rnGraphics )
364 {
365  try
366  {
367  awt::Size aLogicalSize( 28000, 21000 );
368  Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW );
369  xPropertySet->getPropertyValue( "Width" ) >>= aLogicalSize.Width;
370  xPropertySet->getPropertyValue( "Height" ) >>= aLogicalSize.Height;
371 
372  Reference< XPropertySet > xBackgroundPropSet;
373  if ( xPropertySet->getPropertyValue( "Background" ) >>= xBackgroundPropSet )
374  {
375  FillStyle eFillStyle;
376  if ( xBackgroundPropSet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
377  {
378  if ( eFillStyle == FillStyle_BITMAP )
379  {
380  rnGraphics++;
381  }
382  }
383  }
384  }
385  catch( Exception& )
386  {
387  }
388 }
389 
390 void GraphicCollector::CountGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel,
391  const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics )
392 {
393  try
394  {
395  sal_Int32 i;
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++ )
399  {
400  Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
401  ImpCountBackgroundGraphic( xDrawPage, rnGraphics );
402  ImpCountGraphicObjects( rxMSF, xDrawPage, rGraphicSettings, rnGraphics );
403 
404  Reference< XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
405  Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
406  ImpCountBackgroundGraphic( xNotesPage, rnGraphics );
407  ImpCountGraphicObjects( rxMSF, xNotesPage, rGraphicSettings, rnGraphics );
408  }
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++ )
412  {
413  Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW );
414  ImpCountBackgroundGraphic( xMasterPage, rnGraphics );
415  ImpCountGraphicObjects( rxMSF, xMasterPage, rGraphicSettings, rnGraphics );
416  }
417  }
418  catch ( Exception& )
419  {
420  }
421 }
422 
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XFrame > xFrame
static void ImpCollectBackgroundGraphic(const Reference< XComponentContext > &rxMSF, const Reference< XDrawPage > &rxDrawPage, const GraphicSettings &rGraphicSettings, std::vector< GraphicCollector::GraphicEntity > &rGraphicEntities)
css::uno::Reference< css::graphic::XGraphic > mxGraphic
bool const mbEmbedLinkedGraphics
static void ImpCountBackgroundGraphic(const Reference< XDrawPage > &rxDrawPage, sal_Int32 &rnGraphics)
static void CountGraphics(const css::uno::Reference< css::uno::XComponentContext > &rxMSF, const css::uno::Reference< css::frame::XModel > &rxModel, const GraphicSettings &rGraphicSettings, sal_Int32 &rGraphics)
static void ImpAddFillBitmapEntity(const Reference< XComponentContext > &rxMSF, const Reference< XPropertySet > &rxPropertySet, const awt::Size &rLogicalSize, std::vector< GraphicCollector::GraphicEntity > &rGraphicEntities, const GraphicSettings &rGraphicSettings, const Reference< XPropertySet > &rxPagePropertySet)
if(nullptr==pCandidateA||nullptr==pCandidateB)
css::uno::Reference< css::beans::XPropertySet > mxPagePropertySet
static void ImpAddGraphicEntity(const Reference< XComponentContext > &rxMSF, Reference< XShape > const &rxShape, const GraphicSettings &rGraphicSettings, std::vector< GraphicCollector::GraphicEntity > &rGraphicEntities)
static css::awt::Size GetOriginalSize(const css::uno::Reference< css::uno::XComponentContext > &rxMSF, const css::uno::Reference< css::graphic::XGraphic > &rxGraphic)
css::uno::Reference< css::beans::XPropertySet > mxPropertySet
int i
css::uno::Reference< css::drawing::XShape > mxShape
css::text::GraphicCrop maGraphicCropLogic
static void ImpCollectGraphicObjects(const Reference< XComponentContext > &rxMSF, const Reference< XShapes > &rxShapes, const GraphicSettings &rGraphicSettings, std::vector< GraphicCollector::GraphicEntity > &rGraphicEntities)
static void CollectGraphics(const css::uno::Reference< css::uno::XComponentContext > &rxMSF, const css::uno::Reference< css::frame::XModel > &rxModel, const GraphicSettings &rGraphicSettings, std::vector< GraphicEntity > &io_rGraphicList)
static const css::awt::DeviceInfo & GetDeviceInfo(const css::uno::Reference< css::uno::XComponentContext > &rxFact)
static void ImpAddEntity(std::vector< GraphicCollector::GraphicEntity > &rGraphicEntities, const GraphicSettings &rGraphicSettings, const GraphicCollector::GraphicUser &rUser)
Reference< XGraphic > xGraphic
static void ImpCountGraphicObjects(const Reference< XComponentContext > &rxMSF, const Reference< XShapes > &rxShapes, const GraphicSettings &rGraphicSettings, sal_Int32 &rnGraphics)