/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sdext.hxx" #include "graphiccollector.hxx" #include #include #include #include #include #include #include #include "impoptimizer.hxx" using namespace ::rtl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::graphic; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::presentation; const DeviceInfo& GraphicCollector::GetDeviceInfo( const Reference< XComponentContext >& rxFact ) { static DeviceInfo aDeviceInfo; if( !aDeviceInfo.Width ) { try { Reference< XFramesSupplier > xDesktop( rxFact->getServiceManager()->createInstanceWithContext( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), rxFact ), UNO_QUERY_THROW ); Reference< XFrame > xFrame( xDesktop->getActiveFrame() ); Reference< XWindow > xWindow( xFrame->getContainerWindow() ); Reference< XDevice > xDevice( xWindow, UNO_QUERY_THROW ); aDeviceInfo = xDevice->getInfo(); } catch( Exception& ) { } } return aDeviceInfo; } void ImpAddEntity( std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities, Reference< XGraphic >& rxGraphic, const GraphicSettings& rGraphicSettings, const GraphicCollector::GraphicUser& rUser ) { const rtl::OUString aGraphicURL( rUser.maGraphicURL ); const rtl::OUString sPackageURL( OUString::createFromAscii( "vnd.sun.star.GraphicObject:" ) ); if ( rGraphicSettings.mbEmbedLinkedGraphics || ( !aGraphicURL.getLength() || aGraphicURL.match( sPackageURL, 0 ) ) ) { std::vector< GraphicCollector::GraphicEntity >::iterator aIter( rGraphicEntities.begin() ); while( aIter != rGraphicEntities.end() ) { if ( aIter->maUser[ 0 ].maGraphicURL == aGraphicURL ) { if ( rUser.maLogicalSize.Width > aIter->maLogicalSize.Width ) aIter->maLogicalSize.Width = rUser.maLogicalSize.Width; if ( rUser.maLogicalSize.Height > aIter->maLogicalSize.Height ) aIter->maLogicalSize.Height = rUser.maLogicalSize.Height; aIter->maUser.push_back( rUser ); break; } aIter++; } if ( aIter == rGraphicEntities.end() ) { GraphicCollector::GraphicEntity aEntity( rxGraphic, rUser ); rGraphicEntities.push_back( aEntity ); } } } void ImpAddGraphicEntity( const Reference< XComponentContext >& rxMSF, Reference< XShape >& rxShape, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities ) { Reference< XGraphic > xGraphic; Reference< XPropertySet > xShapePropertySet( rxShape, UNO_QUERY_THROW ); if ( xShapePropertySet->getPropertyValue( TKGet( TK_Graphic ) ) >>= xGraphic ) { text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 ); GraphicCollector::GraphicUser aUser; aUser.mxShape = rxShape; aUser.mbFillBitmap = sal_False; xShapePropertySet->getPropertyValue( TKGet( TK_GraphicURL ) ) >>= aUser.maGraphicURL; xShapePropertySet->getPropertyValue( TKGet( TK_GraphicStreamURL ) ) >>= aUser.maGraphicStreamURL; xShapePropertySet->getPropertyValue( TKGet( TK_GraphicCrop ) ) >>= aGraphicCropLogic; awt::Size aLogicalSize( rxShape->getSize() ); // calculating the logical size, as if there were no cropping if ( aGraphicCropLogic.Left || aGraphicCropLogic.Right || aGraphicCropLogic.Top || aGraphicCropLogic.Bottom ) { awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) ); if ( aSize100thMM.Width && aSize100thMM.Height ) { awt::Size aCropSize( aSize100thMM.Width - ( aGraphicCropLogic.Left + aGraphicCropLogic.Right ), aSize100thMM.Height - ( aGraphicCropLogic.Top + aGraphicCropLogic.Bottom )); if ( aCropSize.Width && aCropSize.Height ) { awt::Size aNewLogSize( static_cast< sal_Int32 >( static_cast< double >( aSize100thMM.Width * aLogicalSize.Width ) / aCropSize.Width ), static_cast< sal_Int32 >( static_cast< double >( aSize100thMM.Height * aLogicalSize.Height ) / aCropSize.Height ) ); aLogicalSize = aNewLogSize; } } } aUser.maGraphicCropLogic = aGraphicCropLogic; aUser.maLogicalSize = aLogicalSize; ImpAddEntity( rGraphicEntities, xGraphic, rGraphicSettings, aUser ); } } 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 ) { try { FillStyle eFillStyle; if ( rxPropertySet->getPropertyValue( TKGet( TK_FillStyle ) ) >>= eFillStyle ) { if ( eFillStyle == FillStyle_BITMAP ) { rtl::OUString aFillBitmapURL; Reference< XBitmap > xFillBitmap; if ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmap ) ) >>= xFillBitmap ) { Reference< XGraphic > xGraphic( xFillBitmap, UNO_QUERY_THROW ); if ( xGraphic.is() ) { awt::Size aLogicalSize( rLogicalSize ); Reference< XPropertySetInfo > axPropSetInfo( rxPropertySet->getPropertySetInfo() ); if ( axPropSetInfo.is() ) { if ( axPropSetInfo->hasPropertyByName( TKGet( TK_FillBitmapMode ) ) ) { BitmapMode eBitmapMode; if ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapMode ) ) >>= eBitmapMode ) { if ( ( eBitmapMode == BitmapMode_REPEAT ) || ( eBitmapMode == BitmapMode_NO_REPEAT ) ) { sal_Bool bLogicalSize = sal_False; awt::Size aSize( 0, 0 ); if ( ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapLogicalSize ) ) >>= bLogicalSize ) && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeX ) ) >>= aSize.Width ) && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeY ) ) >>= aSize.Height ) ) { if ( bLogicalSize ) { if ( !aSize.Width || !aSize.Height ) { awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) ); if ( aSize100thMM.Width && aSize100thMM.Height ) aLogicalSize = aSize100thMM; } else aLogicalSize = aSize; } else { aLogicalSize.Width = sal::static_int_cast< sal_Int32 >( ( static_cast< double >( aLogicalSize.Width ) * aSize.Width ) / -100.0 ); aLogicalSize.Height = sal::static_int_cast< sal_Int32 >( ( static_cast< double >( aLogicalSize.Height ) * aSize.Height ) / -100.0 ); } } } } } } GraphicCollector::GraphicUser aUser; aUser.mxPropertySet = rxPropertySet; rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapURL ) ) >>= aUser.maGraphicURL; aUser.mbFillBitmap = sal_True; aUser.maLogicalSize = aLogicalSize; aUser.mxPagePropertySet = rxPagePropertySet; ImpAddEntity( rGraphicEntities, xGraphic, rGraphicSettings, aUser ); } } } } } catch( Exception& ) { } } void ImpCollectBackgroundGraphic( const Reference< XComponentContext >& rxMSF, const Reference< XDrawPage >& rxDrawPage, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities ) { try { awt::Size aLogicalSize( 28000, 21000 ); Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW ); xPropertySet->getPropertyValue( TKGet( TK_Width ) ) >>= aLogicalSize.Width; xPropertySet->getPropertyValue( TKGet( TK_Height ) ) >>= aLogicalSize.Height; Reference< XPropertySet > xBackgroundPropSet; if ( xPropertySet->getPropertyValue( TKGet( TK_Background ) ) >>= xBackgroundPropSet ) ImpAddFillBitmapEntity( rxMSF, xBackgroundPropSet, aLogicalSize, rGraphicEntities, rGraphicSettings, xPropertySet ); } catch( Exception& ) { } } void ImpCollectGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities ) { for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ ) { try { const OUString sGraphicObjectShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicObjectShape" ) ); const OUString sGroupShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GroupShape" ) ); Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW ); const OUString sShapeType( xShape->getShapeType() ); if ( sShapeType == sGroupShape ) { Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW ); ImpCollectGraphicObjects( rxMSF, xShapes, rGraphicSettings, rGraphicEntities ); continue; } if ( sShapeType == sGraphicObjectShape ) ImpAddGraphicEntity( rxMSF, xShape, rGraphicSettings, rGraphicEntities ); // now check for a fillstyle Reference< XPropertySet > xEmptyPagePropSet; Reference< XPropertySet > xShapePropertySet( xShape, UNO_QUERY_THROW ); awt::Size aLogicalSize( xShape->getSize() ); ImpAddFillBitmapEntity( rxMSF, xShapePropertySet, aLogicalSize, rGraphicEntities, rGraphicSettings, xEmptyPagePropSet ); } catch( Exception& ) { } } } awt::Size GraphicCollector::GetOriginalSize( const Reference< XComponentContext >& rxMSF, const Reference< XGraphic >& rxGraphic ) { awt::Size aSize100thMM( 0, 0 ); Reference< XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW ); if ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Size100thMM ) ) >>= aSize100thMM ) { if ( !aSize100thMM.Width && !aSize100thMM.Height ) { // MAPMODE_PIXEL USED :-( awt::Size aSourceSizePixel( 0, 0 ); if ( xGraphicPropertySet->getPropertyValue( TKGet( TK_SizePixel ) ) >>= aSourceSizePixel ) { const DeviceInfo& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF ) ); if ( rDeviceInfo.PixelPerMeterX && rDeviceInfo.PixelPerMeterY ) { aSize100thMM.Width = static_cast< sal_Int32 >( ( aSourceSizePixel.Width * 100000.0 ) / rDeviceInfo.PixelPerMeterX ); aSize100thMM.Height = static_cast< sal_Int32 >( ( aSourceSizePixel.Height * 100000.0 ) / rDeviceInfo.PixelPerMeterY ); } } } } return aSize100thMM; } void GraphicCollector::CollectGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicList ) { try { sal_Int32 i; Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); for ( i = 0; i < xDrawPages->getCount(); i++ ) { Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW ); ImpCollectBackgroundGraphic( rxMSF, xDrawPage, rGraphicSettings, rGraphicList ); Reference< XShapes > xDrawShapes( xDrawPage, UNO_QUERY_THROW ); ImpCollectGraphicObjects( rxMSF, xDrawShapes, rGraphicSettings, rGraphicList ); Reference< XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW ); Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() ); ImpCollectBackgroundGraphic( rxMSF, xNotesPage, rGraphicSettings, rGraphicList ); Reference< XShapes > xNotesShapes( xNotesPage, UNO_QUERY_THROW ); ImpCollectGraphicObjects( rxMSF, xNotesShapes, rGraphicSettings, rGraphicList ); } Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW ); Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY_THROW ); for ( i = 0; i < xMasterPages->getCount(); i++ ) { Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW ); ImpCollectBackgroundGraphic( rxMSF, xMasterPage, rGraphicSettings, rGraphicList ); Reference< XShapes > xMasterPageShapes( xMasterPage, UNO_QUERY_THROW ); ImpCollectGraphicObjects( rxMSF, xMasterPageShapes, rGraphicSettings, rGraphicList ); } std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIter( rGraphicList.begin() ); std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIEnd( rGraphicList.end() ); while( aGraphicIter != aGraphicIEnd ) { // check if it is possible to remove the crop area aGraphicIter->mbRemoveCropArea = rGraphicSettings.mbRemoveCropArea; if ( aGraphicIter->mbRemoveCropArea ) { std::vector< GraphicCollector::GraphicUser >::iterator aGUIter( aGraphicIter->maUser.begin() ); while( aGraphicIter->mbRemoveCropArea && ( aGUIter != aGraphicIter->maUser.end() ) ) { if ( aGUIter->maGraphicCropLogic.Left || aGUIter->maGraphicCropLogic.Top || aGUIter->maGraphicCropLogic.Right || aGUIter->maGraphicCropLogic.Bottom ) { if ( aGUIter == aGraphicIter->maUser.begin() ) aGraphicIter->maGraphicCropLogic = aGUIter->maGraphicCropLogic; else if ( ( aGraphicIter->maGraphicCropLogic.Left != aGUIter->maGraphicCropLogic.Left ) || ( aGraphicIter->maGraphicCropLogic.Top != aGUIter->maGraphicCropLogic.Top ) || ( aGraphicIter->maGraphicCropLogic.Right != aGUIter->maGraphicCropLogic.Right ) || ( aGraphicIter->maGraphicCropLogic.Bottom != aGUIter->maGraphicCropLogic.Bottom ) ) { aGraphicIter->mbRemoveCropArea = sal_False; } } else aGraphicIter->mbRemoveCropArea = sal_False; aGUIter++; } } if ( !aGraphicIter->mbRemoveCropArea ) aGraphicIter->maGraphicCropLogic = text::GraphicCrop( 0, 0, 0, 0 ); aGraphicIter++; } } catch ( Exception& ) { } } void ImpCountGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics ) { for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ ) { try { const OUString sGraphicObjectShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicObjectShape" ) ); const OUString sGroupShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GroupShape" ) ); Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW ); const OUString sShapeType( xShape->getShapeType() ); if ( sShapeType == sGroupShape ) { Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW ); ImpCountGraphicObjects( rxMSF, xShapes, rGraphicSettings, rnGraphics ); continue; } if ( sShapeType == sGraphicObjectShape ) { rnGraphics++; } // now check for a fillstyle Reference< XPropertySet > xEmptyPagePropSet; Reference< XPropertySet > xShapePropertySet( xShape, UNO_QUERY_THROW ); awt::Size aLogicalSize( xShape->getSize() ); FillStyle eFillStyle; if ( xShapePropertySet->getPropertyValue( TKGet( TK_FillStyle ) ) >>= eFillStyle ) { if ( eFillStyle == FillStyle_BITMAP ) { rnGraphics++; } } } catch( Exception& ) { } } } void ImpCountBackgroundGraphic( const Reference< XComponentContext >& /* rxMSF */, const Reference< XDrawPage >& rxDrawPage, const GraphicSettings& /* rGraphicSettings */, sal_Int32& rnGraphics ) { try { awt::Size aLogicalSize( 28000, 21000 ); Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW ); xPropertySet->getPropertyValue( TKGet( TK_Width ) ) >>= aLogicalSize.Width; xPropertySet->getPropertyValue( TKGet( TK_Height ) ) >>= aLogicalSize.Height; Reference< XPropertySet > xBackgroundPropSet; if ( xPropertySet->getPropertyValue( TKGet( TK_Background ) ) >>= xBackgroundPropSet ) { FillStyle eFillStyle; if ( xBackgroundPropSet->getPropertyValue( TKGet( TK_FillStyle ) ) >>= eFillStyle ) { if ( eFillStyle == FillStyle_BITMAP ) { rnGraphics++; } } } } catch( Exception& ) { } } void GraphicCollector::CountGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel, const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics ) { try { sal_Int32 i; Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); for ( i = 0; i < xDrawPages->getCount(); i++ ) { Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW ); ImpCountBackgroundGraphic( rxMSF, xDrawPage, rGraphicSettings, rnGraphics ); Reference< XShapes > xDrawShapes( xDrawPage, UNO_QUERY_THROW ); ImpCountGraphicObjects( rxMSF, xDrawShapes, rGraphicSettings, rnGraphics ); Reference< XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW ); Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() ); ImpCountBackgroundGraphic( rxMSF, xNotesPage, rGraphicSettings, rnGraphics ); Reference< XShapes > xNotesShapes( xNotesPage, UNO_QUERY_THROW ); ImpCountGraphicObjects( rxMSF, xNotesShapes, rGraphicSettings, rnGraphics ); } Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW ); Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY_THROW ); for ( i = 0; i < xMasterPages->getCount(); i++ ) { Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW ); ImpCountBackgroundGraphic( rxMSF, xMasterPage, rGraphicSettings, rnGraphics ); Reference< XShapes > xMasterPageShapes( xMasterPage, UNO_QUERY_THROW ); ImpCountGraphicObjects( rxMSF, xMasterPageShapes, rGraphicSettings, rnGraphics ); } } catch ( Exception& ) { } }