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

Generated by: LCOV version 1.10