LCOV - code coverage report
Current view: top level - svtools/source/graphic - provider.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 200 452 44.2 %
Date: 2015-06-13 12:38:46 Functions: 19 24 79.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include <osl/mutex.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <vcl/image.hxx>
      23             : #include <vcl/metaact.hxx>
      24             : #include <vcl/msgbox.hxx>
      25             : #include <vcl/imagerepository.hxx>
      26             : #include <tools/rcid.h>
      27             : #include <tools/resid.hxx>
      28             : #include <tools/resmgr.hxx>
      29             : #include <tools/fract.hxx>
      30             : #include <unotools/ucbstreamhelper.hxx>
      31             : #include <vcl/graphicfilter.hxx>
      32             : #include <vcl/wmf.hxx>
      33             : #include <svl/solar.hrc>
      34             : #include <vcl/virdev.hxx>
      35             : #include <vcl/settings.hxx>
      36             : #include <com/sun/star/io/XStream.hpp>
      37             : #include <com/sun/star/text/GraphicCrop.hpp>
      38             : #include <com/sun/star/uno/XComponentContext.hpp>
      39             : #include <comphelper/servicehelper.hxx>
      40             : #include <cppuhelper/supportsservice.hxx>
      41             : 
      42             : #include "descriptor.hxx"
      43             : #include "graphic.hxx"
      44             : #include <rtl/ref.hxx>
      45             : #include <svtools/grfmgr.hxx>
      46             : #include "provider.hxx"
      47             : #include <vcl/dibtools.hxx>
      48             : #include <boost/scoped_ptr.hpp>
      49             : 
      50             : using namespace com::sun::star;
      51             : 
      52             : namespace {
      53             : 
      54             : #define UNO_NAME_GRAPHOBJ_URLPREFIX                             "vnd.sun.star.GraphicObject:"
      55             : 
      56       86406 : GraphicProvider::GraphicProvider()
      57             : {
      58       86406 : }
      59             : 
      60      172810 : GraphicProvider::~GraphicProvider()
      61             : {
      62      172810 : }
      63             : 
      64           1 : OUString SAL_CALL GraphicProvider::getImplementationName()
      65             :     throw( uno::RuntimeException, std::exception )
      66             : {
      67           1 :     return OUString( "com.sun.star.comp.graphic.GraphicProvider" );
      68             : }
      69             : 
      70           0 : sal_Bool SAL_CALL GraphicProvider::supportsService( const OUString& ServiceName )
      71             :     throw( uno::RuntimeException, std::exception )
      72             : {
      73           0 :     return cppu::supportsService( this, ServiceName );
      74             : }
      75             : 
      76           1 : uno::Sequence< OUString > SAL_CALL GraphicProvider::getSupportedServiceNames()
      77             :     throw( uno::RuntimeException, std::exception )
      78             : {
      79           1 :     uno::Sequence< OUString > aSeq( 1 );
      80           1 :     aSeq.getArray()[ 0 ] = "com.sun.star.graphic.GraphicProvider";
      81           1 :     return aSeq;
      82             : }
      83             : 
      84           0 : uno::Sequence< uno::Type > SAL_CALL GraphicProvider::getTypes()
      85             :     throw(uno::RuntimeException, std::exception)
      86             : {
      87           0 :     uno::Sequence< uno::Type >  aTypes( 3 );
      88           0 :     uno::Type*                  pTypes = aTypes.getArray();
      89             : 
      90           0 :     *pTypes++ = cppu::UnoType<lang::XServiceInfo>::get();
      91           0 :     *pTypes++ = cppu::UnoType<lang::XTypeProvider>::get();
      92           0 :     *pTypes++ = cppu::UnoType<graphic::XGraphicProvider>::get();
      93             : 
      94           0 :     return aTypes;
      95             : }
      96             : 
      97           0 : uno::Sequence< sal_Int8 > SAL_CALL GraphicProvider::getImplementationId()
      98             :     throw(uno::RuntimeException, std::exception)
      99             : {
     100           0 :     return css::uno::Sequence<sal_Int8>();
     101             : }
     102             : 
     103             : 
     104             : 
     105        4103 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadGraphicObject( const OUString& rResourceURL )
     106             : {
     107        4103 :     uno::Reference< ::graphic::XGraphic >   xRet;
     108        4103 :     if( rResourceURL.startsWith( UNO_NAME_GRAPHOBJ_URLPREFIX ) )
     109             :     {
     110             :         // graphic manager url
     111         278 :         OUString aTmpStr( rResourceURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 ) );
     112             :         OString aUniqueID(OUStringToOString(aTmpStr,
     113         556 :             RTL_TEXTENCODING_UTF8));
     114         556 :         GraphicObject aGrafObj(aUniqueID);
     115             :         // I don't call aGrafObj.GetXGraphic because it will call us back
     116             :         // into implLoadMemory ( with "private:memorygraphic" test )
     117         278 :         ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
     118         278 :         pUnoGraphic->init( aGrafObj.GetGraphic() );
     119         556 :         xRet = pUnoGraphic;
     120             :     }
     121        4103 :     return xRet;
     122             : }
     123             : 
     124       84030 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadMemory( const OUString& rResourceURL )
     125             : {
     126       84030 :     uno::Reference< ::graphic::XGraphic >   xRet;
     127       84030 :     sal_Int32                               nIndex = 0;
     128             : 
     129       84030 :     if( rResourceURL.getToken( 0, '/', nIndex ) == "private:memorygraphic" )
     130             :     {
     131       79927 :         sal_Int64 nGraphicAddress = rResourceURL.getToken( 0, '/', nIndex ).toInt64();
     132             : 
     133       79927 :         if( nGraphicAddress )
     134             :         {
     135       79927 :             ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
     136             : 
     137       79927 :             pUnoGraphic->init( *reinterpret_cast< ::Graphic* >( nGraphicAddress ) );
     138       79927 :             xRet = pUnoGraphic;
     139             :         }
     140             :     }
     141             : 
     142       84030 :     return xRet;
     143             : }
     144             : 
     145             : 
     146             : 
     147        3825 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadRepositoryImage( const OUString& rResourceURL )
     148             : {
     149        3825 :     uno::Reference< ::graphic::XGraphic >   xRet;
     150        3825 :     sal_Int32                               nIndex = 0;
     151             : 
     152        3825 :     if( rResourceURL.getToken( 0, '/', nIndex ) == "private:graphicrepository" )
     153             :     {
     154        3796 :         OUString sPathName( rResourceURL.copy( nIndex ) );
     155        7592 :         BitmapEx aBitmap;
     156        3796 :         if ( vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) )
     157             :         {
     158        3796 :             Image aImage( aBitmap );
     159        3796 :             xRet = aImage.GetXGraphic();
     160        3796 :         }
     161             :     }
     162        3825 :     return xRet;
     163             : }
     164             : 
     165             : 
     166             : 
     167             : 
     168          29 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadStandardImage( const OUString& rResourceURL )
     169             : {
     170          29 :     uno::Reference< ::graphic::XGraphic >   xRet;
     171          29 :     sal_Int32                               nIndex = 0;
     172             : 
     173          29 :     if( rResourceURL.getToken( 0, '/', nIndex ) == "private:standardimage" )
     174             :     {
     175           0 :         OUString sImageName( rResourceURL.copy( nIndex ) );
     176           0 :         if ( sImageName == "info" )
     177             :         {
     178           0 :             xRet = InfoBox::GetStandardImage().GetXGraphic();
     179             :         }
     180           0 :         else if ( sImageName == "warning" )
     181             :         {
     182           0 :             xRet = WarningBox::GetStandardImage().GetXGraphic();
     183             :         }
     184           0 :         else if ( sImageName == "error" )
     185             :         {
     186           0 :             xRet = ErrorBox::GetStandardImage().GetXGraphic();
     187             :         }
     188           0 :         else if ( sImageName == "query" )
     189             :         {
     190           0 :             xRet = QueryBox::GetStandardImage().GetXGraphic();
     191           0 :         }
     192             :     }
     193          29 :     return xRet;
     194             : }
     195             : 
     196             : 
     197             : 
     198           0 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const uno::Reference< awt::XBitmap >& xBtm )
     199             : {
     200           0 :     uno::Reference< ::graphic::XGraphic > xRet;
     201           0 :     uno::Sequence< sal_Int8 > aBmpSeq( xBtm->getDIB() );
     202           0 :     uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() );
     203           0 :     SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), StreamMode::READ );
     204           0 :     Bitmap aBmp;
     205           0 :     BitmapEx aBmpEx;
     206             : 
     207           0 :     ReadDIB(aBmp, aBmpStream, true);
     208             : 
     209           0 :     if( aMaskSeq.getLength() )
     210             :     {
     211           0 :         SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), StreamMode::READ );
     212           0 :         Bitmap aMask;
     213             : 
     214           0 :         ReadDIB(aMask, aMaskStream, true);
     215           0 :         aBmpEx = BitmapEx( aBmp, aMask );
     216             :     }
     217             :     else
     218           0 :         aBmpEx = BitmapEx( aBmp );
     219             : 
     220           0 :     if( !aBmpEx.IsEmpty() )
     221             :     {
     222           0 :         ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
     223             : 
     224           0 :         pUnoGraphic->init( aBmpEx );
     225           0 :         xRet = pUnoGraphic;
     226             :     }
     227           0 :     return xRet;
     228             : }
     229             : 
     230             : 
     231             : 
     232        3825 : uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadResource( const OUString& rResourceURL )
     233             : {
     234        3825 :     uno::Reference< ::graphic::XGraphic >   xRet;
     235        3825 :     sal_Int32                               nIndex = 0;
     236             : 
     237        3825 :     if( rResourceURL.getToken( 0, '/', nIndex ) == "private:resource" )
     238             :     {
     239             :         OString aResMgrName(OUStringToOString(
     240           0 :             rResourceURL.getToken(0, '/', nIndex), RTL_TEXTENCODING_ASCII_US));
     241             : 
     242           0 :         boost::scoped_ptr<ResMgr> pResMgr(ResMgr::CreateResMgr( aResMgrName.getStr(), Application::GetSettings().GetUILanguageTag() ));
     243             : 
     244           0 :         if( pResMgr )
     245             :         {
     246           0 :             const OUString   aResourceType( rResourceURL.getToken( 0, '/', nIndex ) );
     247           0 :             const ResId             aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr );
     248             : 
     249           0 :             if( !aResourceType.isEmpty() )
     250             :             {
     251           0 :                 BitmapEx aBmpEx;
     252             : 
     253           0 :                 if( aResourceType == "bitmap" || aResourceType == "bitmapex" )
     254             :                 {
     255           0 :                     aResId.SetRT( RSC_BITMAP );
     256             : 
     257           0 :                     if( pResMgr->IsAvailable( aResId ) )
     258             :                     {
     259           0 :                         aBmpEx = BitmapEx( aResId );
     260             :                     }
     261             :                 }
     262           0 :                 else if( aResourceType == "image" )
     263             :                 {
     264           0 :                     aResId.SetRT( RSC_IMAGE );
     265             : 
     266           0 :                     if( pResMgr->IsAvailable( aResId ) )
     267             :                     {
     268           0 :                         const Image aImage( aResId );
     269           0 :                         aBmpEx = aImage.GetBitmapEx();
     270             :                     }
     271             :                 }
     272           0 :                 else if( aResourceType == "imagelist" )
     273             :                 {
     274           0 :                     aResId.SetRT( RSC_IMAGELIST );
     275             : 
     276           0 :                     if( pResMgr->IsAvailable( aResId ) )
     277             :                     {
     278           0 :                         const ImageList aImageList( aResId );
     279           0 :                         sal_Int32       nImageId = ( nIndex > -1 ) ? rResourceURL.getToken( 0, '/', nIndex ).toInt32() : 0;
     280             : 
     281           0 :                         if( 0 < nImageId )
     282             :                         {
     283           0 :                             const Image aImage( aImageList.GetImage( sal::static_int_cast< sal_uInt16 >(nImageId) ) );
     284           0 :                             aBmpEx = aImage.GetBitmapEx();
     285             :                         }
     286             :                         else
     287             :                         {
     288           0 :                             aBmpEx = aImageList.GetAsHorizontalStrip();
     289           0 :                         }
     290             :                     }
     291             :                 }
     292             : 
     293           0 :                 if( !aBmpEx.IsEmpty() )
     294             :                 {
     295           0 :                     ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
     296             : 
     297           0 :                     pUnoGraphic->init( aBmpEx );
     298           0 :                     xRet = pUnoGraphic;
     299           0 :                 }
     300           0 :             }
     301           0 :         }
     302             :     }
     303             : 
     304        3825 :     return xRet;
     305             : }
     306             : 
     307             : 
     308             : 
     309           0 : uno::Reference< beans::XPropertySet > SAL_CALL GraphicProvider::queryGraphicDescriptor( const uno::Sequence< beans::PropertyValue >& rMediaProperties )
     310             :     throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     311             : {
     312           0 :     uno::Reference< beans::XPropertySet > xRet;
     313             : 
     314           0 :     OUString aURL;
     315           0 :     uno::Reference< io::XInputStream > xIStm;
     316           0 :     uno::Reference< awt::XBitmap >xBtm;
     317             : 
     318           0 :     for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !xRet.is(); ++i )
     319             :     {
     320           0 :         const OUString   aName( rMediaProperties[ i ].Name );
     321           0 :         const uno::Any          aValue( rMediaProperties[ i ].Value );
     322             : 
     323           0 :         if (aName == "URL")
     324             :         {
     325           0 :             aValue >>= aURL;
     326             :         }
     327           0 :         else if (aName == "InputStream")
     328             :         {
     329           0 :             aValue >>= xIStm;
     330             :         }
     331           0 :         else if (aName == "Bitmap")
     332             :         {
     333           0 :             aValue >>= xBtm;
     334             :         }
     335           0 :     }
     336             : 
     337           0 :     SolarMutexGuard g;
     338             : 
     339           0 :     if( xIStm.is() )
     340             :     {
     341           0 :         unographic::GraphicDescriptor* pDescriptor = new unographic::GraphicDescriptor;
     342           0 :         pDescriptor->init( xIStm, aURL );
     343           0 :         xRet = pDescriptor;
     344             :     }
     345           0 :     else if( !aURL.isEmpty() )
     346             :     {
     347           0 :         uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) );
     348           0 :         if( !xGraphic.is() )
     349           0 :             xGraphic = implLoadResource( aURL );
     350           0 :         if( !xGraphic.is() )
     351           0 :             xGraphic = implLoadGraphicObject( aURL );
     352             : 
     353           0 :         if ( !xGraphic.is() )
     354           0 :             xGraphic = implLoadRepositoryImage( aURL );
     355             : 
     356           0 :         if ( !xGraphic.is() )
     357           0 :             xGraphic = implLoadStandardImage( aURL );
     358             : 
     359           0 :         if( xGraphic.is() )
     360             :         {
     361           0 :             xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
     362             :         }
     363             :         else
     364             :         {
     365           0 :             unographic::GraphicDescriptor* pDescriptor = new unographic::GraphicDescriptor;
     366           0 :             pDescriptor->init( aURL );
     367           0 :             xRet = pDescriptor;
     368           0 :         }
     369             :     }
     370           0 :     else if( xBtm.is() )
     371             :     {
     372           0 :         uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) );
     373           0 :         if( xGraphic.is() )
     374           0 :             xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
     375             :     }
     376             : 
     377           0 :     return xRet;
     378             : }
     379             : 
     380             : 
     381             : 
     382       84661 : uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( const uno::Sequence< ::beans::PropertyValue >& rMediaProperties )
     383             :     throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     384             : {
     385       84661 :     uno::Reference< ::graphic::XGraphic >   xRet;
     386      169322 :     OUString                                aPath;
     387      169322 :     boost::scoped_ptr<SvStream>             pIStm;
     388             : 
     389      169322 :     uno::Reference< io::XInputStream > xIStm;
     390      169322 :     uno::Reference< awt::XBitmap >xBtm;
     391             : 
     392      169322 :     uno::Sequence< ::beans::PropertyValue > aFilterData;
     393             : 
     394      169329 :     for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && !xRet.is(); ++i )
     395             :     {
     396       84668 :         const OUString   aName( rMediaProperties[ i ].Name );
     397      169336 :         const uno::Any          aValue( rMediaProperties[ i ].Value );
     398             : 
     399       84668 :         if (aName == "URL")
     400             :         {
     401       84116 :             OUString aURL;
     402       84116 :             aValue >>= aURL;
     403       84116 :             aPath = aURL;
     404             :         }
     405         552 :         else if (aName == "InputStream")
     406             :         {
     407         545 :             aValue >>= xIStm;
     408             :         }
     409           7 :         else if (aName == "Bitmap")
     410             :         {
     411           0 :             aValue >>= xBtm;
     412             :         }
     413           7 :         else if (aName == "FilterData")
     414             :         {
     415           7 :             aValue >>= aFilterData;
     416             :         }
     417       84668 :     }
     418             : 
     419             :     // Check for the goal width and height if they are defined
     420       84661 :     sal_uInt16 nExtWidth = 0;
     421       84661 :     sal_uInt16 nExtHeight = 0;
     422       84661 :     sal_uInt16 nExtMapMode = 0;
     423       84682 :     for( sal_Int32 i = 0; i < aFilterData.getLength(); ++i )
     424             :     {
     425          21 :         const OUString   aName( aFilterData[ i ].Name );
     426          42 :         const uno::Any          aValue( aFilterData[ i ].Value );
     427             : 
     428          21 :         if (aName == "ExternalWidth")
     429             :         {
     430           7 :             aValue >>= nExtWidth;
     431             :         }
     432          14 :         else if (aName == "ExternalHeight")
     433             :         {
     434           7 :             aValue >>= nExtHeight;
     435             :         }
     436           7 :         else if (aName == "ExternalMapMode")
     437             :         {
     438           7 :             aValue >>= nExtMapMode;
     439             :         }
     440          21 :     }
     441             : 
     442      169322 :     SolarMutexGuard g;
     443             : 
     444       84661 :     if( xIStm.is() )
     445             :     {
     446         545 :         pIStm.reset(::utl::UcbStreamHelper::CreateStream( xIStm ));
     447             :     }
     448       84116 :     else if( !aPath.isEmpty() )
     449             :     {
     450       84030 :         xRet = implLoadMemory( aPath );
     451             : 
     452       84030 :         if( !xRet.is() )
     453        4103 :             xRet = implLoadGraphicObject( aPath );
     454             : 
     455       84030 :         if( !xRet.is() )
     456        3825 :             xRet = implLoadResource( aPath );
     457             : 
     458       84030 :         if ( !xRet.is() )
     459        3825 :             xRet = implLoadRepositoryImage( aPath );
     460             : 
     461       84030 :         if ( !xRet.is() )
     462          29 :             xRet = implLoadStandardImage( aPath );
     463             : 
     464       84030 :         if( !xRet.is() )
     465          29 :             pIStm.reset(::utl::UcbStreamHelper::CreateStream( aPath, StreamMode::READ ));
     466             :     }
     467          86 :     else if( xBtm.is() )
     468             :     {
     469           0 :         xRet = implLoadBitmap( xBtm );
     470             :     }
     471             : 
     472       84661 :     if( pIStm )
     473             :     {
     474         574 :         ::GraphicFilter& rFilter = ::GraphicFilter::GetGraphicFilter();
     475             : 
     476             :         {
     477         574 :             ::Graphic aVCLGraphic;
     478             : 
     479             :             // Define APM Header if goal height and width are defined
     480         574 :             WMF_EXTERNALHEADER aExtHeader;
     481         574 :             aExtHeader.xExt = nExtWidth;
     482         574 :             aExtHeader.yExt = nExtHeight;
     483         574 :             aExtHeader.mapMode = nExtMapMode;
     484         574 :             WMF_EXTERNALHEADER *pExtHeader = NULL;
     485         574 :             if ( nExtMapMode > 0 )
     486           7 :                 pExtHeader = &aExtHeader;
     487             : 
     488        1148 :             if( ( rFilter.ImportGraphic( aVCLGraphic, aPath, *pIStm,
     489        1118 :                                          GRFILTER_FORMAT_DONTKNOW, NULL, GraphicFilterImportFlags::NONE, pExtHeader ) == GRFILTER_OK ) &&
     490         544 :                 ( aVCLGraphic.GetType() != GRAPHIC_NONE ) )
     491             :             {
     492         544 :                 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
     493             : 
     494         544 :                 pUnoGraphic->init( aVCLGraphic );
     495         544 :                 xRet = pUnoGraphic;
     496         574 :             }
     497             :         }
     498             :     }
     499             : 
     500      169322 :     return xRet;
     501             : }
     502             : 
     503           1 : void ImplCalculateCropRect( ::Graphic& rGraphic, const text::GraphicCrop& rGraphicCropLogic, Rectangle& rGraphicCropPixel )
     504             : {
     505           1 :     if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
     506             :     {
     507           0 :         Size aSourceSizePixel( rGraphic.GetSizePixel() );
     508           0 :         if ( aSourceSizePixel.Width() && aSourceSizePixel.Height() )
     509             :         {
     510           0 :             if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
     511             :             {
     512           0 :                 Size aSize100thMM( 0, 0 );
     513           0 :                 if( rGraphic.GetPrefMapMode().GetMapUnit() != MAP_PIXEL )
     514             :                 {
     515           0 :                     aSize100thMM = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), MAP_100TH_MM );
     516             :                 }
     517             :                 else
     518             :                 {
     519           0 :                     aSize100thMM = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), MAP_100TH_MM );
     520             :                 }
     521           0 :                 if ( aSize100thMM.Width() && aSize100thMM.Height() )
     522             :                 {
     523           0 :                     double fSourceSizePixelWidth = static_cast<double>(aSourceSizePixel.Width());
     524           0 :                     double fSourceSizePixelHeight= static_cast<double>(aSourceSizePixel.Height());
     525           0 :                     rGraphicCropPixel.Left() = static_cast< sal_Int32 >((fSourceSizePixelWidth * rGraphicCropLogic.Left ) / aSize100thMM.Width());
     526           0 :                     rGraphicCropPixel.Top() = static_cast< sal_Int32 >((fSourceSizePixelHeight * rGraphicCropLogic.Top ) / aSize100thMM.Height());
     527           0 :                     rGraphicCropPixel.Right() = static_cast< sal_Int32 >(( fSourceSizePixelWidth * ( aSize100thMM.Width() - rGraphicCropLogic.Right ) ) / aSize100thMM.Width() );
     528           0 :                     rGraphicCropPixel.Bottom() = static_cast< sal_Int32 >(( fSourceSizePixelHeight * ( aSize100thMM.Height() - rGraphicCropLogic.Bottom ) ) / aSize100thMM.Height() );
     529             :                 }
     530             :             }
     531             :         }
     532             :     }
     533           1 : }
     534             : 
     535           1 : void ImplApplyBitmapScaling( ::Graphic& rGraphic, sal_Int32 nPixelWidth, sal_Int32 nPixelHeight )
     536             : {
     537           1 :     if ( nPixelWidth && nPixelHeight )
     538             :     {
     539           0 :         BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
     540           0 :         MapMode aPrefMapMode( aBmpEx.GetPrefMapMode() );
     541           0 :         Size    aPrefSize( aBmpEx.GetPrefSize() );
     542           0 :         aBmpEx.Scale( Size( nPixelWidth, nPixelHeight ) );
     543           0 :         aBmpEx.SetPrefMapMode( aPrefMapMode );
     544           0 :         aBmpEx.SetPrefSize( aPrefSize );
     545           0 :         rGraphic = aBmpEx;
     546             :     }
     547           1 : }
     548             : 
     549           1 : void ImplApplyBitmapResolution( ::Graphic& rGraphic, sal_Int32 nImageResolution, const Size& rVisiblePixelSize, const awt::Size& rLogicalSize )
     550             : {
     551           1 :     if ( nImageResolution && rLogicalSize.Width && rLogicalSize.Height )
     552             :     {
     553           0 :         const double fImageResolution = static_cast<double>( nImageResolution );
     554           0 :         const double fSourceDPIX = ( static_cast<double>(rVisiblePixelSize.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize.Width);
     555           0 :         const double fSourceDPIY = ( static_cast<double>(rVisiblePixelSize.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize.Height);
     556           0 :         const sal_Int32 nSourcePixelWidth( rGraphic.GetSizePixel().Width() );
     557           0 :         const sal_Int32 nSourcePixelHeight( rGraphic.GetSizePixel().Height() );
     558           0 :         const double fSourcePixelWidth = static_cast<double>( nSourcePixelWidth );
     559           0 :         const double fSourcePixelHeight= static_cast<double>( nSourcePixelHeight );
     560             : 
     561           0 :         sal_Int32 nDestPixelWidth = nSourcePixelWidth;
     562           0 :         sal_Int32 nDestPixelHeight = nSourcePixelHeight;
     563             : 
     564             :         // check, if the bitmap DPI exceeds the maximum DPI
     565           0 :         if( fSourceDPIX > fImageResolution )
     566             :         {
     567           0 :             nDestPixelWidth = static_cast<sal_Int32>(( fSourcePixelWidth * fImageResolution ) / fSourceDPIX);
     568           0 :             if ( !nDestPixelWidth || ( nDestPixelWidth > nSourcePixelWidth ) )
     569           0 :                 nDestPixelWidth = nSourcePixelWidth;
     570             :         }
     571           0 :         if ( fSourceDPIY > fImageResolution )
     572             :         {
     573           0 :             nDestPixelHeight= static_cast<sal_Int32>(( fSourcePixelHeight* fImageResolution ) / fSourceDPIY);
     574           0 :             if ( !nDestPixelHeight || ( nDestPixelHeight > nSourcePixelHeight ) )
     575           0 :                 nDestPixelHeight = nSourcePixelHeight;
     576             :         }
     577           0 :         if ( ( nDestPixelWidth != nSourcePixelWidth ) || ( nDestPixelHeight != nSourcePixelHeight ) )
     578           0 :             ImplApplyBitmapScaling( rGraphic, nDestPixelWidth, nDestPixelHeight );
     579             :     }
     580           1 : }
     581             : 
     582           1 : void ImplApplyFilterData( ::Graphic& rGraphic, uno::Sequence< beans::PropertyValue >& rFilterData )
     583             : {
     584             :     /* this method applies following attributes to the graphic, in the first step the
     585             :        cropping area (logical size in 100thmm) is applied, in the second step the resolution
     586             :        is applied, in the third step the graphic is scaled to the corresponding pixelsize.
     587             :        if a parameter value is zero or not available the corresponding step will be skipped */
     588             : 
     589           1 :     sal_Int32 nPixelWidth = 0;
     590           1 :     sal_Int32 nPixelHeight= 0;
     591           1 :     sal_Int32 nImageResolution = 0;
     592           1 :     awt::Size aLogicalSize( 0, 0 );
     593           1 :     text::GraphicCrop aCropLogic( 0, 0, 0, 0 );
     594           1 :     bool bRemoveCropArea = true;
     595             : 
     596           1 :     for( sal_Int32 i = 0; i < rFilterData.getLength(); ++i )
     597             :     {
     598           0 :         const OUString   aName(  rFilterData[ i ].Name );
     599           0 :         const uno::Any          aValue( rFilterData[ i ].Value );
     600             : 
     601           0 :         if (aName == "PixelWidth")
     602           0 :             aValue >>= nPixelWidth;
     603           0 :         else if (aName == "PixelHeight")
     604           0 :             aValue >>= nPixelHeight;
     605           0 :         else if (aName == "LogicalSize")
     606           0 :             aValue >>= aLogicalSize;
     607           0 :         else if (aName == "GraphicCropLogic")
     608           0 :             aValue >>= aCropLogic;
     609           0 :         else if (aName == "RemoveCropArea")
     610           0 :             aValue >>= bRemoveCropArea;
     611           0 :         else if (aName == "ImageResolution")
     612           0 :             aValue >>= nImageResolution;
     613           0 :     }
     614           1 :     if ( rGraphic.GetType() == GRAPHIC_BITMAP )
     615             :     {
     616           1 :         if(rGraphic.getSvgData().get())
     617             :         {
     618             :             // embedded Svg, no need to scale. Also no method to apply crop data currently
     619             :         }
     620             :         else
     621             :         {
     622           1 :             Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() );
     623           1 :             ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel );
     624           1 :             if ( bRemoveCropArea )
     625             :             {
     626           1 :                 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
     627           1 :                 aBmpEx.Crop( aCropPixel );
     628           1 :                 rGraphic = aBmpEx;
     629             :             }
     630           1 :             Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() );
     631           1 :             ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize );
     632           1 :             ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight );
     633             :         }
     634             :     }
     635           0 :     else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution )
     636             :     {
     637           0 :         ScopedVclPtrInstance< VirtualDevice > aDummyVDev;
     638           0 :         GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
     639           0 :         Size aMtfSize( OutputDevice::LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_100TH_MM ) );
     640           0 :         if ( aMtfSize.Width() && aMtfSize.Height() )
     641             :         {
     642           0 :             MapMode aNewMapMode( MAP_100TH_MM );
     643           0 :             aNewMapMode.SetScaleX( static_cast< double >( aLogicalSize.Width ) / static_cast< double >( aMtfSize.Width() ) );
     644           0 :             aNewMapMode.SetScaleY( static_cast< double >( aLogicalSize.Height ) / static_cast< double >( aMtfSize.Height() ) );
     645           0 :             aDummyVDev->EnableOutput( false );
     646           0 :             aDummyVDev->SetMapMode( aNewMapMode );
     647             : 
     648           0 :             for( size_t i = 0, nObjCount = aMtf.GetActionSize(); i < nObjCount; i++ )
     649             :             {
     650           0 :                 MetaAction* pAction = aMtf.GetAction( i );
     651           0 :                 switch( pAction->GetType() )
     652             :                 {
     653             :                     // only optimizing common bitmap actions:
     654             :                     case( MetaActionType::MAPMODE ):
     655             :                     {
     656           0 :                         pAction->Execute( aDummyVDev.get() );
     657           0 :                         break;
     658             :                     }
     659             :                     case( MetaActionType::PUSH ):
     660             :                     {
     661           0 :                         const MetaPushAction* pA = static_cast<const MetaPushAction*>(pAction);
     662           0 :                         aDummyVDev->Push( pA->GetFlags() );
     663           0 :                         break;
     664             :                     }
     665             :                     case( MetaActionType::POP ):
     666             :                     {
     667           0 :                         aDummyVDev->Pop();
     668           0 :                         break;
     669             :                     }
     670             :                     case( MetaActionType::BMPSCALE ):
     671             :                     case( MetaActionType::BMPEXSCALE ):
     672             :                     {
     673           0 :                         BitmapEx aBmpEx;
     674           0 :                         Point aPos;
     675           0 :                         Size aSize;
     676           0 :                         if ( pAction->GetType() == MetaActionType::BMPSCALE )
     677             :                         {
     678           0 :                             MetaBmpScaleAction* pScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction );
     679           0 :                             aBmpEx = pScaleAction->GetBitmap();
     680           0 :                             aPos = pScaleAction->GetPoint();
     681           0 :                             aSize = pScaleAction->GetSize();
     682             :                         }
     683             :                         else
     684             :                         {
     685           0 :                             MetaBmpExScaleAction* pScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction );
     686           0 :                             aBmpEx = pScaleAction->GetBitmapEx();
     687           0 :                             aPos = pScaleAction->GetPoint();
     688           0 :                             aSize = pScaleAction->GetSize();
     689             :                         }
     690           0 :                         ::Graphic aGraphic( aBmpEx );
     691           0 :                         const Size aSize100thmm( aDummyVDev->LogicToPixel( aSize ) );
     692           0 :                         Size aSize100thmm2( aDummyVDev->PixelToLogic( aSize100thmm, MAP_100TH_MM ) );
     693             : 
     694             :                         ImplApplyBitmapResolution( aGraphic, nImageResolution,
     695           0 :                             aGraphic.GetSizePixel(), awt::Size( aSize100thmm2.Width(), aSize100thmm2.Height() ) );
     696             : 
     697             :                         MetaAction* pNewAction;
     698           0 :                         if ( pAction->GetType() == MetaActionType::BMPSCALE )
     699           0 :                             pNewAction = new MetaBmpScaleAction ( aPos, aSize, aGraphic.GetBitmap() );
     700             :                         else
     701           0 :                             pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() );
     702             : 
     703           0 :                         MetaAction* pDeleteAction = aMtf.ReplaceAction( pNewAction, i );
     704           0 :                         if(pDeleteAction)
     705           0 :                             pDeleteAction->Delete();
     706           0 :                         break;
     707             :                     }
     708             :                     default:
     709             :                     case( MetaActionType::BMP ):
     710             :                     case( MetaActionType::BMPSCALEPART ):
     711             :                     case( MetaActionType::BMPEX ):
     712             :                     case( MetaActionType::BMPEXSCALEPART ):
     713             :                     case( MetaActionType::MASK ):
     714             :                     case( MetaActionType::MASKSCALE ):
     715           0 :                     break;
     716             :                 }
     717             :             }
     718           0 :             rGraphic = aMtf;
     719           0 :         }
     720             :     }
     721           1 : }
     722             : 
     723             : 
     724             : 
     725           1 : void SAL_CALL GraphicProvider::storeGraphic( const uno::Reference< ::graphic::XGraphic >& rxGraphic, const uno::Sequence< beans::PropertyValue >& rMediaProperties )
     726             :     throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
     727             : {
     728           1 :     SolarMutexGuard g;
     729             : 
     730           2 :     boost::scoped_ptr<SvStream> pOStm;
     731           2 :     OUString    aPath;
     732             :     sal_Int32   i;
     733             : 
     734           3 :     for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i )
     735             :     {
     736           2 :         const OUString   aName( rMediaProperties[ i ].Name );
     737           4 :         const uno::Any          aValue( rMediaProperties[ i ].Value );
     738             : 
     739           2 :         if (aName == "URL")
     740             :         {
     741           0 :             OUString aURL;
     742             : 
     743           0 :             aValue >>= aURL;
     744           0 :             pOStm.reset(::utl::UcbStreamHelper::CreateStream( aURL, StreamMode::WRITE | StreamMode::TRUNC ));
     745           0 :             aPath = aURL;
     746             :         }
     747           2 :         else if (aName == "OutputStream")
     748             :         {
     749           1 :             uno::Reference< io::XStream > xOStm;
     750             : 
     751           1 :             aValue >>= xOStm;
     752             : 
     753           1 :             if( xOStm.is() )
     754           1 :                 pOStm.reset(::utl::UcbStreamHelper::CreateStream( xOStm ));
     755             :         }
     756           2 :     }
     757             : 
     758           1 :     if( pOStm )
     759             :     {
     760           1 :         uno::Sequence< beans::PropertyValue >   aFilterDataSeq;
     761           1 :         const char*                             pFilterShortName = NULL;
     762             : 
     763           3 :         for( i = 0; i < rMediaProperties.getLength(); ++i )
     764             :         {
     765           2 :             const OUString   aName( rMediaProperties[ i ].Name );
     766           4 :             const uno::Any          aValue( rMediaProperties[ i ].Value );
     767             : 
     768           2 :             if (aName == "FilterData")
     769             :             {
     770           0 :                 aValue >>= aFilterDataSeq;
     771             :             }
     772           2 :             else if (aName == "MimeType")
     773             :             {
     774           1 :                 OUString aMimeType;
     775             : 
     776           1 :                 aValue >>= aMimeType;
     777             : 
     778           1 :                 if (aMimeType == MIMETYPE_BMP)
     779           0 :                     pFilterShortName = "bmp";
     780           1 :                 else if (aMimeType == MIMETYPE_EPS)
     781           0 :                     pFilterShortName = "eps";
     782           1 :                 else if (aMimeType == MIMETYPE_GIF)
     783           0 :                     pFilterShortName = "gif";
     784           1 :                 else if (aMimeType == MIMETYPE_JPG)
     785           0 :                     pFilterShortName = "jpg";
     786           1 :                 else if (aMimeType == MIMETYPE_MET)
     787           0 :                     pFilterShortName = "met";
     788           1 :                 else if (aMimeType == MIMETYPE_PNG)
     789           1 :                     pFilterShortName = "png";
     790           0 :                 else if (aMimeType == MIMETYPE_PCT)
     791           0 :                     pFilterShortName = "pct";
     792           0 :                 else if (aMimeType == MIMETYPE_PBM)
     793           0 :                     pFilterShortName = "pbm";
     794           0 :                 else if (aMimeType == MIMETYPE_PGM)
     795           0 :                     pFilterShortName = "pgm";
     796           0 :                 else if (aMimeType == MIMETYPE_PPM)
     797           0 :                     pFilterShortName = "ppm";
     798           0 :                 else if (aMimeType == MIMETYPE_RAS)
     799           0 :                     pFilterShortName = "ras";
     800           0 :                 else if (aMimeType == MIMETYPE_SVM)
     801           0 :                     pFilterShortName = "svm";
     802           0 :                 else if (aMimeType == MIMETYPE_TIF)
     803           0 :                     pFilterShortName = "tif";
     804           0 :                 else if (aMimeType == MIMETYPE_EMF)
     805           0 :                     pFilterShortName = "emf";
     806           0 :                 else if (aMimeType == MIMETYPE_WMF)
     807           0 :                     pFilterShortName = "wmf";
     808           0 :                 else if (aMimeType == MIMETYPE_XPM)
     809           0 :                     pFilterShortName = "xpm";
     810           0 :                 else if (aMimeType == MIMETYPE_SVG)
     811           0 :                     pFilterShortName = "svg";
     812           0 :                 else if (aMimeType == MIMETYPE_VCLGRAPHIC)
     813           0 :                     pFilterShortName = MIMETYPE_VCLGRAPHIC;
     814             :             }
     815           2 :         }
     816             : 
     817           1 :         if( pFilterShortName )
     818             :         {
     819           1 :             ::GraphicFilter& rFilter = ::GraphicFilter::GetGraphicFilter();
     820             : 
     821             :             {
     822           1 :                 const uno::Reference< XInterface >  xIFace( rxGraphic, uno::UNO_QUERY );
     823           1 :                 const ::Graphic*                    pGraphic = ::unographic::Graphic::getImplementation( xIFace );
     824             : 
     825           1 :                 if( pGraphic && ( pGraphic->GetType() != GRAPHIC_NONE ) )
     826             :                 {
     827           1 :                     ::Graphic aGraphic( *pGraphic );
     828           1 :                     ImplApplyFilterData( aGraphic, aFilterDataSeq );
     829             : 
     830             :                     /* sj: using a temporary memory stream, because some graphic filters are seeking behind
     831             :                        stream end (which leads to an invalid argument exception then). */
     832           2 :                     SvMemoryStream aMemStrm;
     833           1 :                     aMemStrm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
     834           1 :                     if( 0 == strcmp( pFilterShortName, MIMETYPE_VCLGRAPHIC ) )
     835           0 :                         WriteGraphic( aMemStrm, aGraphic );
     836             :                     else
     837             :                     {
     838             :                         rFilter.ExportGraphic( aGraphic, aPath, aMemStrm,
     839           2 :                                                 rFilter.GetExportFormatNumberForShortName( OUString::createFromAscii( pFilterShortName ) ),
     840           2 :                                                     ( aFilterDataSeq.getLength() ? &aFilterDataSeq : NULL ) );
     841             :                     }
     842           1 :                     aMemStrm.Seek( STREAM_SEEK_TO_END );
     843           2 :                     pOStm->Write( aMemStrm.GetData(), aMemStrm.Tell() );
     844           1 :                 }
     845             :             }
     846           1 :         }
     847           1 :     }
     848           1 : }
     849             : 
     850             : }
     851             : 
     852             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     853       86406 : com_sun_star_comp_graphic_GraphicProvider_get_implementation(
     854             :     css::uno::XComponentContext *,
     855             :     css::uno::Sequence<css::uno::Any> const &)
     856             : {
     857       86406 :     return cppu::acquire(new GraphicProvider);
     858         798 : }
     859             : 
     860             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11