Update ooo320-m1
[ooovba.git] / goodies / source / unographic / provider.cxx
blob753109d23c4bda67b4660105d3d0da6e5931beeb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: provider.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
33 #include <rtl/uuid.h>
34 #include <vos/mutex.hxx>
35 #ifndef _SV_SVAPP_HXX_
36 #include <vcl/svapp.hxx>
37 #endif
38 #ifndef _SV_IMAGE_HXX_
39 #include <vcl/image.hxx>
40 #endif
41 #include <vcl/metaact.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <vcl/imagerepository.hxx>
44 #include <tools/rcid.h>
45 #include <tools/resid.hxx>
46 #include <tools/resmgr.hxx>
47 #include <unotools/ucbstreamhelper.hxx>
48 #include <svtools/filter.hxx>
49 #include <svtools/solar.hrc>
50 #include <vcl/salbtype.hxx>
51 #include <vcl/virdev.hxx>
52 #include <com/sun/star/io/XStream.hpp>
53 #include <com/sun/star/text/GraphicCrop.hpp>
55 #include "descriptor.hxx"
56 #include "graphic.hxx"
57 #include "grfmgr.hxx"
58 #include "provider.hxx"
60 using namespace com::sun::star;
62 namespace unographic {
64 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
66 // -------------------
67 // - GraphicProvider -
68 // -------------------
70 GraphicProvider::GraphicProvider()
74 // ------------------------------------------------------------------------------
76 GraphicProvider::~GraphicProvider()
80 // ------------------------------------------------------------------------------
82 ::rtl::OUString GraphicProvider::getImplementationName_Static()
83 throw()
85 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicProvider" ) );
88 // ------------------------------------------------------------------------------
90 uno::Sequence< ::rtl::OUString > GraphicProvider::getSupportedServiceNames_Static()
91 throw()
93 uno::Sequence< ::rtl::OUString > aSeq( 1 );
95 aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) );
97 return aSeq;
100 // ------------------------------------------------------------------------------
102 ::rtl::OUString SAL_CALL GraphicProvider::getImplementationName()
103 throw( uno::RuntimeException )
105 return getImplementationName_Static();
108 // ------------------------------------------------------------------------------
110 sal_Bool SAL_CALL GraphicProvider::supportsService( const ::rtl::OUString& ServiceName )
111 throw( uno::RuntimeException )
113 uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
114 const ::rtl::OUString* pArray = aSNL.getConstArray();
116 for( int i = 0; i < aSNL.getLength(); i++ )
117 if( pArray[i] == ServiceName )
118 return true;
120 return false;
123 // ------------------------------------------------------------------------------
125 uno::Sequence< ::rtl::OUString > SAL_CALL GraphicProvider::getSupportedServiceNames()
126 throw( uno::RuntimeException )
128 return getSupportedServiceNames_Static();
131 // ------------------------------------------------------------------------------
133 uno::Sequence< uno::Type > SAL_CALL GraphicProvider::getTypes()
134 throw(uno::RuntimeException)
136 uno::Sequence< uno::Type > aTypes( 3 );
137 uno::Type* pTypes = aTypes.getArray();
139 *pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
140 *pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
141 *pTypes++ = ::getCppuType((const uno::Reference< graphic::XGraphicProvider>*)0);
143 return aTypes;
146 // ------------------------------------------------------------------------------
148 uno::Sequence< sal_Int8 > SAL_CALL GraphicProvider::getImplementationId()
149 throw(uno::RuntimeException)
151 vos::OGuard aGuard( Application::GetSolarMutex() );
152 static uno::Sequence< sal_Int8 > aId;
154 if( aId.getLength() == 0 )
156 aId.realloc( 16 );
157 rtl_createUuid( reinterpret_cast< sal_uInt8* >( aId.getArray() ), 0, sal_True );
160 return aId;
163 // ------------------------------------------------------------------------------
165 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadGraphicObject( const ::rtl::OUString& rResourceURL ) const
167 uno::Reference< ::graphic::XGraphic > xRet;
168 if( rResourceURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 )
170 // graphic manager url
171 String aTmpStr( rResourceURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 ) );
172 ByteString aUniqueID( aTmpStr, RTL_TEXTENCODING_UTF8 );
173 GraphicObject aGrafObj( aUniqueID );
174 // I don't call aGrafObj.GetXGraphic because it will call us back
175 // into implLoadMemory ( with "private:memorygraphic" test )
176 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
177 pUnoGraphic->init( aGrafObj.GetGraphic() );
178 xRet = pUnoGraphic;
180 return xRet;
183 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadMemory( const ::rtl::OUString& rResourceURL ) const
185 uno::Reference< ::graphic::XGraphic > xRet;
186 sal_Int32 nIndex = 0;
188 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:memorygraphic" ) ) )
190 sal_Int64 nGraphicAddress = rResourceURL.getToken( 0, '/', nIndex ).toInt64();
192 if( nGraphicAddress )
194 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
196 pUnoGraphic->init( *reinterpret_cast< ::Graphic* >( nGraphicAddress ) );
197 xRet = pUnoGraphic;
201 return xRet;
204 // ------------------------------------------------------------------------------
206 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadRepositoryImage( const ::rtl::OUString& rResourceURL ) const
208 uno::Reference< ::graphic::XGraphic > xRet;
209 sal_Int32 nIndex = 0;
211 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:graphicrepository" ) ) )
213 String sPathName( rResourceURL.copy( nIndex ) );
214 BitmapEx aBitmap;
215 if ( ::vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) )
217 Image aImage( aBitmap );
218 xRet = aImage.GetXGraphic();
221 return xRet;
225 // ------------------------------------------------------------------------------
227 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadStandardImage( const ::rtl::OUString& rResourceURL ) const
229 uno::Reference< ::graphic::XGraphic > xRet;
230 sal_Int32 nIndex = 0;
232 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:standardimage" ) ) )
234 rtl::OUString sImageName( rResourceURL.copy( nIndex ) );
235 if ( sImageName.compareToAscii( "info" ) )
237 xRet = InfoBox::GetStandardImage().GetXGraphic();
239 else if ( sImageName.compareToAscii( "warning" ) )
241 xRet = WarningBox::GetStandardImage().GetXGraphic();
243 else if ( sImageName.compareToAscii( "error" ) )
245 xRet = ErrorBox::GetStandardImage().GetXGraphic();
247 else if ( sImageName.compareToAscii( "query" ) )
249 xRet = QueryBox::GetStandardImage().GetXGraphic();
252 return xRet;
255 // ------------------------------------------------------------------------------
257 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const uno::Reference< awt::XBitmap >& xBtm ) const
259 uno::Reference< ::graphic::XGraphic > xRet;
260 uno::Sequence< sal_Int8 > aBmpSeq( xBtm->getDIB() );
261 uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() );
262 SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), STREAM_READ );
263 Bitmap aBmp;
264 aBmpStream >> aBmp;
266 BitmapEx aBmpEx;
268 if( aMaskSeq.getLength() )
270 SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), STREAM_READ );
271 Bitmap aMask;
272 aMaskStream >> aMask;
273 aBmpEx = BitmapEx( aBmp, aMask );
275 else
276 aBmpEx = BitmapEx( aBmp );
278 if( !aBmpEx.IsEmpty() )
280 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
282 pUnoGraphic->init( aBmpEx );
283 xRet = pUnoGraphic;
285 return xRet;
288 // ------------------------------------------------------------------------------
290 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadResource( const ::rtl::OUString& rResourceURL ) const
292 uno::Reference< ::graphic::XGraphic > xRet;
293 sal_Int32 nIndex = 0;
295 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:resource" ) ) )
297 ByteString aResMgrName( String( rResourceURL.getToken( 0, '/', nIndex ) ), RTL_TEXTENCODING_ASCII_US );
299 ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
301 if( pResMgr )
303 const ::rtl::OUString aResourceType( rResourceURL.getToken( 0, '/', nIndex ) );
304 const ResId aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr );
306 if( aResourceType.getLength() )
308 BitmapEx aBmpEx;
310 if( ( 0 == aResourceType.compareToAscii( "bitmap" ) ) ||
311 ( 0 == aResourceType.compareToAscii( "bitmapex" ) ) )
313 aResId.SetRT( RSC_BITMAP );
315 if( pResMgr->IsAvailable( aResId ) )
317 aBmpEx = BitmapEx( aResId );
320 else if( 0 == aResourceType.compareToAscii( "image" ) )
322 aResId.SetRT( RSC_IMAGE );
324 if( pResMgr->IsAvailable( aResId ) )
326 const Image aImage( aResId );
327 aBmpEx = aImage.GetBitmapEx();
330 else if( 0 == aResourceType.compareToAscii( "imagelist" ) )
332 aResId.SetRT( RSC_IMAGELIST );
334 if( pResMgr->IsAvailable( aResId ) )
336 const ImageList aImageList( aResId );
337 sal_Int32 nImageId = ( nIndex > -1 ) ? rResourceURL.getToken( 0, '/', nIndex ).toInt32() : 0;
339 if( 0 < nImageId )
341 const Image aImage( aImageList.GetImage( sal::static_int_cast< USHORT >(nImageId) ) );
342 aBmpEx = aImage.GetBitmapEx();
344 else
346 aBmpEx = aImageList.GetAsHorizontalStrip();
351 if( !aBmpEx.IsEmpty() )
353 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
355 pUnoGraphic->init( aBmpEx );
356 xRet = pUnoGraphic;
360 delete pResMgr;
364 return xRet;
367 // ------------------------------------------------------------------------------
369 uno::Reference< beans::XPropertySet > SAL_CALL GraphicProvider::queryGraphicDescriptor( const uno::Sequence< beans::PropertyValue >& rMediaProperties )
370 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
372 uno::Reference< beans::XPropertySet > xRet;
374 ::rtl::OUString aURL;
375 uno::Reference< io::XInputStream > xIStm;
376 uno::Reference< awt::XBitmap >xBtm;
378 for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !xRet.is(); ++i )
380 const ::rtl::OUString aName( rMediaProperties[ i ].Name );
381 const uno::Any aValue( rMediaProperties[ i ].Value );
383 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
385 aValue >>= aURL;
387 else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) )
389 aValue >>= xIStm;
391 else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) )
393 aValue >>= xBtm;
397 if( xIStm.is() )
399 GraphicDescriptor* pDescriptor = new GraphicDescriptor;
400 pDescriptor->init( xIStm, aURL );
401 xRet = pDescriptor;
403 else if( aURL.getLength() )
405 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) );
406 if( !xGraphic.is() )
407 xGraphic = implLoadResource( aURL );
408 if( !xGraphic.is() )
409 xGraphic = implLoadGraphicObject( aURL );
411 if ( !xGraphic.is() )
412 xGraphic = implLoadRepositoryImage( aURL );
414 if ( !xGraphic.is() )
415 xGraphic = implLoadStandardImage( aURL );
417 if( xGraphic.is() )
419 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
421 else
423 GraphicDescriptor* pDescriptor = new GraphicDescriptor;
424 pDescriptor->init( aURL );
425 xRet = pDescriptor;
428 else if( xBtm.is() )
430 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) );
431 if( xGraphic.is() )
432 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
435 return xRet;
438 // ------------------------------------------------------------------------------
440 uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( const uno::Sequence< ::beans::PropertyValue >& rMediaProperties )
441 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
443 uno::Reference< ::graphic::XGraphic > xRet;
444 String aPath;
445 SvStream* pIStm = NULL;
447 uno::Reference< io::XInputStream > xIStm;
448 uno::Reference< awt::XBitmap >xBtm;
450 for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && !xRet.is(); ++i )
452 const ::rtl::OUString aName( rMediaProperties[ i ].Name );
453 const uno::Any aValue( rMediaProperties[ i ].Value );
455 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
457 ::rtl::OUString aURL;
458 aValue >>= aURL;
459 aPath = aURL;
461 else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) )
463 aValue >>= xIStm;
465 else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) )
467 aValue >>= xBtm;
471 if( xIStm.is() )
473 pIStm = ::utl::UcbStreamHelper::CreateStream( xIStm );
475 else if( aPath.Len() )
477 xRet = implLoadMemory( aPath );
479 if( !xRet.is() )
480 xRet = implLoadGraphicObject( aPath );
482 if( !xRet.is() )
483 xRet = implLoadResource( aPath );
485 if ( !xRet.is() )
486 xRet = implLoadRepositoryImage( aPath );
488 if ( !xRet.is() )
489 xRet = implLoadStandardImage( aPath );
491 if( !xRet.is() )
492 pIStm = ::utl::UcbStreamHelper::CreateStream( aPath, STREAM_READ );
494 else if( xBtm.is() )
496 xRet = implLoadBitmap( xBtm );
499 if( pIStm )
501 ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter();
503 if( pFilter )
505 ::Graphic aVCLGraphic;
507 if( ( pFilter->ImportGraphic( aVCLGraphic, aPath, *pIStm ) == GRFILTER_OK ) &&
508 ( aVCLGraphic.GetType() != GRAPHIC_NONE ) )
510 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
512 pUnoGraphic->init( aVCLGraphic );
513 xRet = pUnoGraphic;
517 delete pIStm;
520 return xRet;
523 void ImplCalculateCropRect( ::Graphic& rGraphic, const text::GraphicCrop& rGraphicCropLogic, Rectangle& rGraphicCropPixel )
525 if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
527 Size aSourceSizePixel( rGraphic.GetSizePixel() );
528 if ( aSourceSizePixel.Width() && aSourceSizePixel.Height() )
530 if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom )
532 Size aSize100thMM( 0, 0 );
533 if( rGraphic.GetPrefMapMode().GetMapUnit() != MAP_PIXEL )
535 aSize100thMM = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), MAP_100TH_MM );
537 else
539 aSize100thMM = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), MAP_100TH_MM );
541 if ( aSize100thMM.Width() && aSize100thMM.Height() )
543 double fSourceSizePixelWidth = static_cast<double>(aSourceSizePixel.Width());
544 double fSourceSizePixelHeight= static_cast<double>(aSourceSizePixel.Height());
545 rGraphicCropPixel.Left() = static_cast< sal_Int32 >((fSourceSizePixelWidth * rGraphicCropLogic.Left ) / aSize100thMM.Width());
546 rGraphicCropPixel.Top() = static_cast< sal_Int32 >((fSourceSizePixelHeight * rGraphicCropLogic.Top ) / aSize100thMM.Height());
547 rGraphicCropPixel.Right() = static_cast< sal_Int32 >(( fSourceSizePixelWidth * ( aSize100thMM.Width() - rGraphicCropLogic.Right ) ) / aSize100thMM.Width() );
548 rGraphicCropPixel.Bottom() = static_cast< sal_Int32 >(( fSourceSizePixelHeight * ( aSize100thMM.Height() - rGraphicCropLogic.Bottom ) ) / aSize100thMM.Height() );
555 void ImplApplyBitmapScaling( ::Graphic& rGraphic, sal_Int32 nPixelWidth, sal_Int32 nPixelHeight )
557 if ( nPixelWidth && nPixelHeight )
559 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
560 MapMode aPrefMapMode( aBmpEx.GetPrefMapMode() );
561 Size aPrefSize( aBmpEx.GetPrefSize() );
562 aBmpEx.Scale( Size( nPixelWidth, nPixelHeight ) );
563 aBmpEx.SetPrefMapMode( aPrefMapMode );
564 aBmpEx.SetPrefSize( aPrefSize );
565 rGraphic = aBmpEx;
569 void ImplApplyBitmapResolution( ::Graphic& rGraphic, sal_Int32 nImageResolution, const Size& rVisiblePixelSize, const awt::Size& rLogicalSize )
571 if ( nImageResolution && rLogicalSize.Width && rLogicalSize.Height )
573 const double fImageResolution = static_cast<double>( nImageResolution );
574 const double fSourceDPIX = ( static_cast<double>(rVisiblePixelSize.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize.Width);
575 const double fSourceDPIY = ( static_cast<double>(rVisiblePixelSize.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize.Height);
576 const sal_Int32 nSourcePixelWidth( rGraphic.GetSizePixel().Width() );
577 const sal_Int32 nSourcePixelHeight( rGraphic.GetSizePixel().Height() );
578 const double fSourcePixelWidth = static_cast<double>( nSourcePixelWidth );
579 const double fSourcePixelHeight= static_cast<double>( nSourcePixelHeight );
581 sal_Int32 nDestPixelWidth = nSourcePixelWidth;
582 sal_Int32 nDestPixelHeight = nSourcePixelHeight;
584 // check, if the bitmap DPI exceeds the maximum DPI
585 if( fSourceDPIX > fImageResolution )
587 nDestPixelWidth = static_cast<sal_Int32>(( fSourcePixelWidth * fImageResolution ) / fSourceDPIX);
588 if ( !nDestPixelWidth || ( nDestPixelWidth > nSourcePixelWidth ) )
589 nDestPixelWidth = nSourcePixelWidth;
591 if ( fSourceDPIY > fImageResolution )
593 nDestPixelHeight= static_cast<sal_Int32>(( fSourcePixelHeight* fImageResolution ) / fSourceDPIY);
594 if ( !nDestPixelHeight || ( nDestPixelHeight > nSourcePixelHeight ) )
595 nDestPixelHeight = nSourcePixelHeight;
597 if ( ( nDestPixelWidth != nSourcePixelWidth ) || ( nDestPixelHeight != nSourcePixelHeight ) )
598 ImplApplyBitmapScaling( rGraphic, nDestPixelWidth, nDestPixelHeight );
602 void ImplApplyFilterData( ::Graphic& rGraphic, uno::Sequence< beans::PropertyValue >& rFilterData )
604 /* this method applies following attributes to the graphic, in the first step the
605 cropping area (logical size in 100thmm) is applied, in the second step the resolution
606 is applied, in the third step the graphic is scaled to the corresponding pixelsize.
607 if a parameter value is zero or not available the corresponding step will be skipped */
609 sal_Int32 nPixelWidth = 0;
610 sal_Int32 nPixelHeight= 0;
611 sal_Int32 nImageResolution = 0;
612 awt::Size aLogicalSize( 0, 0 );
613 text::GraphicCrop aCropLogic( 0, 0, 0, 0 );
614 sal_Bool bRemoveCropArea = sal_True;
616 for( sal_Int32 i = 0; i < rFilterData.getLength(); ++i )
618 const ::rtl::OUString aName( rFilterData[ i ].Name );
619 const uno::Any aValue( rFilterData[ i ].Value );
621 if( COMPARE_EQUAL == aName.compareToAscii( "PixelWidth" ) )
622 aValue >>= nPixelWidth;
623 else if( COMPARE_EQUAL == aName.compareToAscii( "PixelHeight" ) )
624 aValue >>= nPixelHeight;
625 else if( COMPARE_EQUAL == aName.compareToAscii( "LogicalSize" ) )
626 aValue >>= aLogicalSize;
627 else if (COMPARE_EQUAL == aName.compareToAscii( "GraphicCropLogic" ) )
628 aValue >>= aCropLogic;
629 else if (COMPARE_EQUAL == aName.compareToAscii( "RemoveCropArea" ) )
630 aValue >>= bRemoveCropArea;
631 else if (COMPARE_EQUAL == aName.compareToAscii( "ImageResolution" ) )
632 aValue >>= nImageResolution;
634 if ( rGraphic.GetType() == GRAPHIC_BITMAP )
636 Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() );
637 ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel );
638 if ( bRemoveCropArea )
640 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
641 aBmpEx.Crop( aCropPixel );
642 rGraphic = aBmpEx;
644 Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() );
645 ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize );
646 ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight );
648 else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution )
650 VirtualDevice aDummyVDev;
651 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
652 Size aMtfSize( aDummyVDev.LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_100TH_MM ) );
653 if ( aMtfSize.Width() && aMtfSize.Height() )
655 MapMode aNewMapMode( MAP_100TH_MM );
656 aNewMapMode.SetScaleX( static_cast< double >( aLogicalSize.Width ) / static_cast< double >( aMtfSize.Width() ) );
657 aNewMapMode.SetScaleY( static_cast< double >( aLogicalSize.Height ) / static_cast< double >( aMtfSize.Height() ) );
658 aDummyVDev.EnableOutput( sal_False );
659 aDummyVDev.SetMapMode( aNewMapMode );
661 for( sal_uInt32 i = 0, nObjCount = aMtf.GetActionCount(); i < nObjCount; i++ )
663 MetaAction* pAction = aMtf.GetAction( i );
664 switch( pAction->GetType() )
666 // only optimizing common bitmap actions:
667 case( META_MAPMODE_ACTION ):
669 const_cast< MetaAction* >( pAction )->Execute( &aDummyVDev );
670 break;
672 case( META_PUSH_ACTION ):
674 const MetaPushAction* pA = (const MetaPushAction*)pAction;
675 aDummyVDev.Push( pA->GetFlags() );
676 break;
678 case( META_POP_ACTION ):
680 aDummyVDev.Pop();
681 break;
683 case( META_BMPSCALE_ACTION ):
684 case( META_BMPEXSCALE_ACTION ):
686 BitmapEx aBmpEx;
687 Point aPos;
688 Size aSize;
689 if ( pAction->GetType() == META_BMPSCALE_ACTION )
691 MetaBmpScaleAction* pScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction );
692 aBmpEx = pScaleAction->GetBitmap();
693 aPos = pScaleAction->GetPoint();
694 aSize = pScaleAction->GetSize();
696 else
698 MetaBmpExScaleAction* pScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction );
699 aBmpEx = pScaleAction->GetBitmapEx();
700 aPos = pScaleAction->GetPoint();
701 aSize = pScaleAction->GetSize();
703 ::Graphic aGraphic( aBmpEx );
704 const Size aSize100thmm( aDummyVDev.LogicToPixel( aSize ) );
705 Size aSize100thmm2( aDummyVDev.PixelToLogic( aSize100thmm, MAP_100TH_MM ) );
707 ImplApplyBitmapResolution( aGraphic, nImageResolution,
708 aGraphic.GetSizePixel(), awt::Size( aSize100thmm2.Width(), aSize100thmm2.Height() ) );
710 MetaAction* pNewAction;
711 if ( pAction->GetType() == META_BMPSCALE_ACTION )
712 pNewAction = new MetaBmpScaleAction ( aPos, aSize, aGraphic.GetBitmap() );
713 else
714 pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() );
716 aMtf.ReplaceAction( pNewAction, i );
717 pAction->Delete();
718 break;
720 default:
721 case( META_BMP_ACTION ):
722 case( META_BMPSCALEPART_ACTION ):
723 case( META_BMPEX_ACTION ):
724 case( META_BMPEXSCALEPART_ACTION ):
725 case( META_MASK_ACTION ):
726 case( META_MASKSCALE_ACTION ):
727 break;
730 rGraphic = aMtf;
735 // ------------------------------------------------------------------------------
737 void SAL_CALL GraphicProvider::storeGraphic( const uno::Reference< ::graphic::XGraphic >& rxGraphic, const uno::Sequence< beans::PropertyValue >& rMediaProperties )
738 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
740 SvStream* pOStm = NULL;
741 String aPath;
742 sal_Int32 i;
744 for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i )
746 const ::rtl::OUString aName( rMediaProperties[ i ].Name );
747 const uno::Any aValue( rMediaProperties[ i ].Value );
749 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) )
751 ::rtl::OUString aURL;
753 aValue >>= aURL;
754 pOStm = ::utl::UcbStreamHelper::CreateStream( aURL, STREAM_WRITE | STREAM_TRUNC );
755 aPath = aURL;
757 else if( COMPARE_EQUAL == aName.compareToAscii( "OutputStream" ) )
759 uno::Reference< io::XStream > xOStm;
761 aValue >>= xOStm;
763 if( xOStm.is() )
764 pOStm = ::utl::UcbStreamHelper::CreateStream( xOStm );
768 if( pOStm )
770 uno::Sequence< beans::PropertyValue > aFilterDataSeq;
771 const char* pFilterShortName = NULL;
773 for( i = 0; i < rMediaProperties.getLength(); ++i )
775 const ::rtl::OUString aName( rMediaProperties[ i ].Name );
776 const uno::Any aValue( rMediaProperties[ i ].Value );
778 if( COMPARE_EQUAL == aName.compareToAscii( "FilterData" ) )
780 aValue >>= aFilterDataSeq;
782 else if( COMPARE_EQUAL == aName.compareToAscii( "MimeType" ) )
784 ::rtl::OUString aMimeType;
786 aValue >>= aMimeType;
788 if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_BMP ) )
789 pFilterShortName = "bmp";
790 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EPS ) )
791 pFilterShortName = "eps";
792 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_GIF ) )
793 pFilterShortName = "gif";
794 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_JPG ) )
795 pFilterShortName = "jpg";
796 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_MET ) )
797 pFilterShortName = "met";
798 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PNG ) )
799 pFilterShortName = "png";
800 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PCT ) )
801 pFilterShortName = "pct";
802 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PBM ) )
803 pFilterShortName = "pbm";
804 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PGM ) )
805 pFilterShortName = "pgm";
806 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PPM ) )
807 pFilterShortName = "ppm";
808 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_RAS ) )
809 pFilterShortName = "ras";
810 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVM ) )
811 pFilterShortName = "svm";
812 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_TIF ) )
813 pFilterShortName = "tif";
814 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EMF ) )
815 pFilterShortName = "emf";
816 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_WMF ) )
817 pFilterShortName = "wmf";
818 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_XPM ) )
819 pFilterShortName = "xpm";
820 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVG ) )
821 pFilterShortName = "svg";
822 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_VCLGRAPHIC ) )
823 pFilterShortName = MIMETYPE_VCLGRAPHIC;
827 if( pFilterShortName )
829 ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter();
831 if( pFilter )
833 const uno::Reference< XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
834 const ::Graphic* pGraphic = ::unographic::Graphic::getImplementation( xIFace );
836 if( pGraphic && ( pGraphic->GetType() != GRAPHIC_NONE ) )
838 ::Graphic aGraphic( *pGraphic );
839 ImplApplyFilterData( aGraphic, aFilterDataSeq );
841 /* sj: using a temporary memory stream, because some graphic filters are seeking behind
842 stream end (which leads to an invalid argument exception then). */
843 SvMemoryStream aMemStrm;
844 aMemStrm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
845 if( 0 == strcmp( pFilterShortName, MIMETYPE_VCLGRAPHIC ) )
846 aMemStrm << aGraphic;
847 else
849 pFilter->ExportGraphic( aGraphic, aPath, aMemStrm,
850 pFilter->GetExportFormatNumberForShortName( ::rtl::OUString::createFromAscii( pFilterShortName ) ),
851 ( aFilterDataSeq.getLength() ? &aFilterDataSeq : NULL ) );
853 aMemStrm.Seek( STREAM_SEEK_TO_END );
854 pOStm->Write( aMemStrm.GetData(), aMemStrm.Tell() );
858 delete pOStm;