1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: provider.cxx,v $
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"
34 #include <vos/mutex.hxx>
35 #ifndef _SV_SVAPP_HXX_
36 #include <vcl/svapp.hxx>
38 #ifndef _SV_IMAGE_HXX_
39 #include <vcl/image.hxx>
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"
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()
85 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicProvider" ) );
88 // ------------------------------------------------------------------------------
90 uno::Sequence
< ::rtl::OUString
> GraphicProvider::getSupportedServiceNames_Static()
93 uno::Sequence
< ::rtl::OUString
> aSeq( 1 );
95 aSeq
.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) );
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
)
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);
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 )
157 rtl_createUuid( reinterpret_cast< sal_uInt8
* >( aId
.getArray() ), 0, sal_True
);
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() );
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
) );
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
) );
215 if ( ::vcl::ImageRepository::loadImage( sPathName
, aBitmap
, false ) )
217 Image
aImage( aBitmap
);
218 xRet
= aImage
.GetXGraphic();
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();
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
);
268 if( aMaskSeq
.getLength() )
270 SvMemoryStream
aMaskStream( aMaskSeq
.getArray(), aMaskSeq
.getLength(), STREAM_READ
);
272 aMaskStream
>> aMask
;
273 aBmpEx
= BitmapEx( aBmp
, aMask
);
276 aBmpEx
= BitmapEx( aBmp
);
278 if( !aBmpEx
.IsEmpty() )
280 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
282 pUnoGraphic
->init( aBmpEx
);
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() );
303 const ::rtl::OUString
aResourceType( rResourceURL
.getToken( 0, '/', nIndex
) );
304 const ResId
aResId( rResourceURL
.getToken( 0, '/', nIndex
).toInt32(), *pResMgr
);
306 if( aResourceType
.getLength() )
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;
341 const Image
aImage( aImageList
.GetImage( sal::static_int_cast
< USHORT
>(nImageId
) ) );
342 aBmpEx
= aImage
.GetBitmapEx();
346 aBmpEx
= aImageList
.GetAsHorizontalStrip();
351 if( !aBmpEx
.IsEmpty() )
353 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
355 pUnoGraphic
->init( aBmpEx
);
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" ) )
387 else if( COMPARE_EQUAL
== aName
.compareToAscii( "InputStream" ) )
391 else if( COMPARE_EQUAL
== aName
.compareToAscii( "Bitmap" ) )
399 GraphicDescriptor
* pDescriptor
= new GraphicDescriptor
;
400 pDescriptor
->init( xIStm
, aURL
);
403 else if( aURL
.getLength() )
405 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadMemory( aURL
) );
407 xGraphic
= implLoadResource( aURL
);
409 xGraphic
= implLoadGraphicObject( aURL
);
411 if ( !xGraphic
.is() )
412 xGraphic
= implLoadRepositoryImage( aURL
);
414 if ( !xGraphic
.is() )
415 xGraphic
= implLoadStandardImage( aURL
);
419 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
423 GraphicDescriptor
* pDescriptor
= new GraphicDescriptor
;
424 pDescriptor
->init( aURL
);
430 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadBitmap( xBtm
) );
432 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
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
;
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
;
461 else if( COMPARE_EQUAL
== aName
.compareToAscii( "InputStream" ) )
465 else if( COMPARE_EQUAL
== aName
.compareToAscii( "Bitmap" ) )
473 pIStm
= ::utl::UcbStreamHelper::CreateStream( xIStm
);
475 else if( aPath
.Len() )
477 xRet
= implLoadMemory( aPath
);
480 xRet
= implLoadGraphicObject( aPath
);
483 xRet
= implLoadResource( aPath
);
486 xRet
= implLoadRepositoryImage( aPath
);
489 xRet
= implLoadStandardImage( aPath
);
492 pIStm
= ::utl::UcbStreamHelper::CreateStream( aPath
, STREAM_READ
);
496 xRet
= implLoadBitmap( xBtm
);
501 ::GraphicFilter
* pFilter
= ::GraphicFilter::GetGraphicFilter();
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
);
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
);
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
);
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
);
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
);
672 case( META_PUSH_ACTION
):
674 const MetaPushAction
* pA
= (const MetaPushAction
*)pAction
;
675 aDummyVDev
.Push( pA
->GetFlags() );
678 case( META_POP_ACTION
):
683 case( META_BMPSCALE_ACTION
):
684 case( META_BMPEXSCALE_ACTION
):
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();
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() );
714 pNewAction
= new MetaBmpExScaleAction( aPos
, aSize
, aGraphic
.GetBitmapEx() );
716 aMtf
.ReplaceAction( pNewAction
, i
);
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
):
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
;
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
;
754 pOStm
= ::utl::UcbStreamHelper::CreateStream( aURL
, STREAM_WRITE
| STREAM_TRUNC
);
757 else if( COMPARE_EQUAL
== aName
.compareToAscii( "OutputStream" ) )
759 uno::Reference
< io::XStream
> xOStm
;
764 pOStm
= ::utl::UcbStreamHelper::CreateStream( xOStm
);
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();
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
;
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() );