1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/mutex.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/image.hxx>
23 #include <vcl/metaact.hxx>
24 #include <vcl/msgbox.hxx>
25 #include <vcl/imagerepository.hxx>
26 #include <tools/rcid.h>
27 #include <tools/resid.hxx>
28 #include <tools/resmgr.hxx>
29 #include <tools/fract.hxx>
30 #include <unotools/ucbstreamhelper.hxx>
31 #include <vcl/graphicfilter.hxx>
32 #include <vcl/wmf.hxx>
33 #include <svl/solar.hrc>
34 #include <vcl/virdev.hxx>
35 #include <vcl/settings.hxx>
36 #include <com/sun/star/io/XStream.hpp>
37 #include <com/sun/star/text/GraphicCrop.hpp>
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 #include <comphelper/servicehelper.hxx>
40 #include <cppuhelper/supportsservice.hxx>
42 #include "descriptor.hxx"
43 #include "graphic.hxx"
44 #include <rtl/ref.hxx>
45 #include <svtools/grfmgr.hxx>
46 #include "provider.hxx"
47 #include <vcl/dibtools.hxx>
48 #include <boost/scoped_ptr.hpp>
50 using namespace com::sun::star
;
54 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
56 GraphicProvider::GraphicProvider()
60 GraphicProvider::~GraphicProvider()
64 OUString SAL_CALL
GraphicProvider::getImplementationName()
65 throw( uno::RuntimeException
, std::exception
)
67 return OUString( "com.sun.star.comp.graphic.GraphicProvider" );
70 sal_Bool SAL_CALL
GraphicProvider::supportsService( const OUString
& ServiceName
)
71 throw( uno::RuntimeException
, std::exception
)
73 return cppu::supportsService( this, ServiceName
);
76 uno::Sequence
< OUString
> SAL_CALL
GraphicProvider::getSupportedServiceNames()
77 throw( uno::RuntimeException
, std::exception
)
79 uno::Sequence
< OUString
> aSeq( 1 );
80 aSeq
.getArray()[ 0 ] = "com.sun.star.graphic.GraphicProvider";
84 uno::Sequence
< uno::Type
> SAL_CALL
GraphicProvider::getTypes()
85 throw(uno::RuntimeException
, std::exception
)
87 uno::Sequence
< uno::Type
> aTypes( 3 );
88 uno::Type
* pTypes
= aTypes
.getArray();
90 *pTypes
++ = cppu::UnoType
<lang::XServiceInfo
>::get();
91 *pTypes
++ = cppu::UnoType
<lang::XTypeProvider
>::get();
92 *pTypes
++ = cppu::UnoType
<graphic::XGraphicProvider
>::get();
97 uno::Sequence
< sal_Int8
> SAL_CALL
GraphicProvider::getImplementationId()
98 throw(uno::RuntimeException
, std::exception
)
100 return css::uno::Sequence
<sal_Int8
>();
105 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadGraphicObject( const OUString
& rResourceURL
)
107 uno::Reference
< ::graphic::XGraphic
> xRet
;
108 if( rResourceURL
.startsWith( UNO_NAME_GRAPHOBJ_URLPREFIX
) )
110 // graphic manager url
111 OUString
aTmpStr( rResourceURL
.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX
) - 1 ) );
112 OString
aUniqueID(OUStringToOString(aTmpStr
,
113 RTL_TEXTENCODING_UTF8
));
114 GraphicObject
aGrafObj(aUniqueID
);
115 // I don't call aGrafObj.GetXGraphic because it will call us back
116 // into implLoadMemory ( with "private:memorygraphic" test )
117 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
118 pUnoGraphic
->init( aGrafObj
.GetGraphic() );
124 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadMemory( const OUString
& rResourceURL
)
126 uno::Reference
< ::graphic::XGraphic
> xRet
;
127 sal_Int32 nIndex
= 0;
129 if( rResourceURL
.getToken( 0, '/', nIndex
) == "private:memorygraphic" )
131 sal_Int64 nGraphicAddress
= rResourceURL
.getToken( 0, '/', nIndex
).toInt64();
133 if( nGraphicAddress
)
135 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
137 pUnoGraphic
->init( *reinterpret_cast< ::Graphic
* >( nGraphicAddress
) );
147 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadRepositoryImage( const OUString
& rResourceURL
)
149 uno::Reference
< ::graphic::XGraphic
> xRet
;
150 sal_Int32 nIndex
= 0;
152 if( rResourceURL
.getToken( 0, '/', nIndex
) == "private:graphicrepository" )
154 OUString
sPathName( rResourceURL
.copy( nIndex
) );
156 if ( vcl::ImageRepository::loadImage( sPathName
, aBitmap
, false ) )
158 Image
aImage( aBitmap
);
159 xRet
= aImage
.GetXGraphic();
168 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadStandardImage( const OUString
& rResourceURL
)
170 uno::Reference
< ::graphic::XGraphic
> xRet
;
171 sal_Int32 nIndex
= 0;
173 if( rResourceURL
.getToken( 0, '/', nIndex
) == "private:standardimage" )
175 OUString
sImageName( rResourceURL
.copy( nIndex
) );
176 if ( sImageName
== "info" )
178 xRet
= InfoBox::GetStandardImage().GetXGraphic();
180 else if ( sImageName
== "warning" )
182 xRet
= WarningBox::GetStandardImage().GetXGraphic();
184 else if ( sImageName
== "error" )
186 xRet
= ErrorBox::GetStandardImage().GetXGraphic();
188 else if ( sImageName
== "query" )
190 xRet
= QueryBox::GetStandardImage().GetXGraphic();
198 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadBitmap( const uno::Reference
< awt::XBitmap
>& xBtm
)
200 uno::Reference
< ::graphic::XGraphic
> xRet
;
201 uno::Sequence
< sal_Int8
> aBmpSeq( xBtm
->getDIB() );
202 uno::Sequence
< sal_Int8
> aMaskSeq( xBtm
->getMaskDIB() );
203 SvMemoryStream
aBmpStream( aBmpSeq
.getArray(), aBmpSeq
.getLength(), StreamMode::READ
);
207 ReadDIB(aBmp
, aBmpStream
, true);
209 if( aMaskSeq
.getLength() )
211 SvMemoryStream
aMaskStream( aMaskSeq
.getArray(), aMaskSeq
.getLength(), StreamMode::READ
);
214 ReadDIB(aMask
, aMaskStream
, true);
215 aBmpEx
= BitmapEx( aBmp
, aMask
);
218 aBmpEx
= BitmapEx( aBmp
);
220 if( !aBmpEx
.IsEmpty() )
222 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
224 pUnoGraphic
->init( aBmpEx
);
232 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadResource( const OUString
& rResourceURL
)
234 uno::Reference
< ::graphic::XGraphic
> xRet
;
235 sal_Int32 nIndex
= 0;
237 if( rResourceURL
.getToken( 0, '/', nIndex
) == "private:resource" )
239 OString
aResMgrName(OUStringToOString(
240 rResourceURL
.getToken(0, '/', nIndex
), RTL_TEXTENCODING_ASCII_US
));
242 boost::scoped_ptr
<ResMgr
> pResMgr(ResMgr::CreateResMgr( aResMgrName
.getStr(), Application::GetSettings().GetUILanguageTag() ));
246 const OUString
aResourceType( rResourceURL
.getToken( 0, '/', nIndex
) );
247 const ResId
aResId( rResourceURL
.getToken( 0, '/', nIndex
).toInt32(), *pResMgr
);
249 if( !aResourceType
.isEmpty() )
253 if( aResourceType
== "bitmap" || aResourceType
== "bitmapex" )
255 aResId
.SetRT( RSC_BITMAP
);
257 if( pResMgr
->IsAvailable( aResId
) )
259 aBmpEx
= BitmapEx( aResId
);
262 else if( aResourceType
== "image" )
264 aResId
.SetRT( RSC_IMAGE
);
266 if( pResMgr
->IsAvailable( aResId
) )
268 const Image
aImage( aResId
);
269 aBmpEx
= aImage
.GetBitmapEx();
272 else if( aResourceType
== "imagelist" )
274 aResId
.SetRT( RSC_IMAGELIST
);
276 if( pResMgr
->IsAvailable( aResId
) )
278 const ImageList
aImageList( aResId
);
279 sal_Int32 nImageId
= ( nIndex
> -1 ) ? rResourceURL
.getToken( 0, '/', nIndex
).toInt32() : 0;
283 const Image
aImage( aImageList
.GetImage( sal::static_int_cast
< sal_uInt16
>(nImageId
) ) );
284 aBmpEx
= aImage
.GetBitmapEx();
288 aBmpEx
= aImageList
.GetAsHorizontalStrip();
293 if( !aBmpEx
.IsEmpty() )
295 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
297 pUnoGraphic
->init( aBmpEx
);
309 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
)
312 uno::Reference
< beans::XPropertySet
> xRet
;
315 uno::Reference
< io::XInputStream
> xIStm
;
316 uno::Reference
< awt::XBitmap
>xBtm
;
318 for( sal_Int32 i
= 0; ( i
< rMediaProperties
.getLength() ) && !xRet
.is(); ++i
)
320 const OUString
aName( rMediaProperties
[ i
].Name
);
321 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
327 else if (aName
== "InputStream")
331 else if (aName
== "Bitmap")
341 unographic::GraphicDescriptor
* pDescriptor
= new unographic::GraphicDescriptor
;
342 pDescriptor
->init( xIStm
, aURL
);
345 else if( !aURL
.isEmpty() )
347 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadMemory( aURL
) );
349 xGraphic
= implLoadResource( aURL
);
351 xGraphic
= implLoadGraphicObject( aURL
);
353 if ( !xGraphic
.is() )
354 xGraphic
= implLoadRepositoryImage( aURL
);
356 if ( !xGraphic
.is() )
357 xGraphic
= implLoadStandardImage( aURL
);
361 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
365 unographic::GraphicDescriptor
* pDescriptor
= new unographic::GraphicDescriptor
;
366 pDescriptor
->init( aURL
);
372 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadBitmap( xBtm
) );
374 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
382 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
)
385 uno::Reference
< ::graphic::XGraphic
> xRet
;
387 boost::scoped_ptr
<SvStream
> pIStm
;
389 uno::Reference
< io::XInputStream
> xIStm
;
390 uno::Reference
< awt::XBitmap
>xBtm
;
392 uno::Sequence
< ::beans::PropertyValue
> aFilterData
;
394 for( sal_Int32 i
= 0; ( i
< rMediaProperties
.getLength() ) && !pIStm
&& !xRet
.is(); ++i
)
396 const OUString
aName( rMediaProperties
[ i
].Name
);
397 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
405 else if (aName
== "InputStream")
409 else if (aName
== "Bitmap")
413 else if (aName
== "FilterData")
415 aValue
>>= aFilterData
;
419 // Check for the goal width and height if they are defined
420 sal_uInt16 nExtWidth
= 0;
421 sal_uInt16 nExtHeight
= 0;
422 sal_uInt16 nExtMapMode
= 0;
423 for( sal_Int32 i
= 0; i
< aFilterData
.getLength(); ++i
)
425 const OUString
aName( aFilterData
[ i
].Name
);
426 const uno::Any
aValue( aFilterData
[ i
].Value
);
428 if (aName
== "ExternalWidth")
430 aValue
>>= nExtWidth
;
432 else if (aName
== "ExternalHeight")
434 aValue
>>= nExtHeight
;
436 else if (aName
== "ExternalMapMode")
438 aValue
>>= nExtMapMode
;
446 pIStm
.reset(::utl::UcbStreamHelper::CreateStream( xIStm
));
448 else if( !aPath
.isEmpty() )
450 xRet
= implLoadMemory( aPath
);
453 xRet
= implLoadGraphicObject( aPath
);
456 xRet
= implLoadResource( aPath
);
459 xRet
= implLoadRepositoryImage( aPath
);
462 xRet
= implLoadStandardImage( aPath
);
465 pIStm
.reset(::utl::UcbStreamHelper::CreateStream( aPath
, StreamMode::READ
));
469 xRet
= implLoadBitmap( xBtm
);
474 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
477 ::Graphic aVCLGraphic
;
479 // Define APM Header if goal height and width are defined
480 WMF_EXTERNALHEADER aExtHeader
;
481 aExtHeader
.xExt
= nExtWidth
;
482 aExtHeader
.yExt
= nExtHeight
;
483 aExtHeader
.mapMode
= nExtMapMode
;
484 WMF_EXTERNALHEADER
*pExtHeader
= NULL
;
485 if ( nExtMapMode
> 0 )
486 pExtHeader
= &aExtHeader
;
488 if( ( rFilter
.ImportGraphic( aVCLGraphic
, aPath
, *pIStm
,
489 GRFILTER_FORMAT_DONTKNOW
, NULL
, GraphicFilterImportFlags::NONE
, pExtHeader
) == GRFILTER_OK
) &&
490 ( aVCLGraphic
.GetType() != GRAPHIC_NONE
) )
492 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
494 pUnoGraphic
->init( aVCLGraphic
);
503 void ImplCalculateCropRect( ::Graphic
& rGraphic
, const text::GraphicCrop
& rGraphicCropLogic
, Rectangle
& rGraphicCropPixel
)
505 if ( rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
)
507 Size
aSourceSizePixel( rGraphic
.GetSizePixel() );
508 if ( aSourceSizePixel
.Width() && aSourceSizePixel
.Height() )
510 if ( rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
)
512 Size
aSize100thMM( 0, 0 );
513 if( rGraphic
.GetPrefMapMode().GetMapUnit() != MAP_PIXEL
)
515 aSize100thMM
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode(), MAP_100TH_MM
);
519 aSize100thMM
= Application::GetDefaultDevice()->PixelToLogic( rGraphic
.GetPrefSize(), MAP_100TH_MM
);
521 if ( aSize100thMM
.Width() && aSize100thMM
.Height() )
523 double fSourceSizePixelWidth
= static_cast<double>(aSourceSizePixel
.Width());
524 double fSourceSizePixelHeight
= static_cast<double>(aSourceSizePixel
.Height());
525 rGraphicCropPixel
.Left() = static_cast< sal_Int32
>((fSourceSizePixelWidth
* rGraphicCropLogic
.Left
) / aSize100thMM
.Width());
526 rGraphicCropPixel
.Top() = static_cast< sal_Int32
>((fSourceSizePixelHeight
* rGraphicCropLogic
.Top
) / aSize100thMM
.Height());
527 rGraphicCropPixel
.Right() = static_cast< sal_Int32
>(( fSourceSizePixelWidth
* ( aSize100thMM
.Width() - rGraphicCropLogic
.Right
) ) / aSize100thMM
.Width() );
528 rGraphicCropPixel
.Bottom() = static_cast< sal_Int32
>(( fSourceSizePixelHeight
* ( aSize100thMM
.Height() - rGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height() );
535 void ImplApplyBitmapScaling( ::Graphic
& rGraphic
, sal_Int32 nPixelWidth
, sal_Int32 nPixelHeight
)
537 if ( nPixelWidth
&& nPixelHeight
)
539 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
540 MapMode
aPrefMapMode( aBmpEx
.GetPrefMapMode() );
541 Size
aPrefSize( aBmpEx
.GetPrefSize() );
542 aBmpEx
.Scale( Size( nPixelWidth
, nPixelHeight
) );
543 aBmpEx
.SetPrefMapMode( aPrefMapMode
);
544 aBmpEx
.SetPrefSize( aPrefSize
);
549 void ImplApplyBitmapResolution( ::Graphic
& rGraphic
, sal_Int32 nImageResolution
, const Size
& rVisiblePixelSize
, const awt::Size
& rLogicalSize
)
551 if ( nImageResolution
&& rLogicalSize
.Width
&& rLogicalSize
.Height
)
553 const double fImageResolution
= static_cast<double>( nImageResolution
);
554 const double fSourceDPIX
= ( static_cast<double>(rVisiblePixelSize
.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Width
);
555 const double fSourceDPIY
= ( static_cast<double>(rVisiblePixelSize
.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Height
);
556 const sal_Int32
nSourcePixelWidth( rGraphic
.GetSizePixel().Width() );
557 const sal_Int32
nSourcePixelHeight( rGraphic
.GetSizePixel().Height() );
558 const double fSourcePixelWidth
= static_cast<double>( nSourcePixelWidth
);
559 const double fSourcePixelHeight
= static_cast<double>( nSourcePixelHeight
);
561 sal_Int32 nDestPixelWidth
= nSourcePixelWidth
;
562 sal_Int32 nDestPixelHeight
= nSourcePixelHeight
;
564 // check, if the bitmap DPI exceeds the maximum DPI
565 if( fSourceDPIX
> fImageResolution
)
567 nDestPixelWidth
= static_cast<sal_Int32
>(( fSourcePixelWidth
* fImageResolution
) / fSourceDPIX
);
568 if ( !nDestPixelWidth
|| ( nDestPixelWidth
> nSourcePixelWidth
) )
569 nDestPixelWidth
= nSourcePixelWidth
;
571 if ( fSourceDPIY
> fImageResolution
)
573 nDestPixelHeight
= static_cast<sal_Int32
>(( fSourcePixelHeight
* fImageResolution
) / fSourceDPIY
);
574 if ( !nDestPixelHeight
|| ( nDestPixelHeight
> nSourcePixelHeight
) )
575 nDestPixelHeight
= nSourcePixelHeight
;
577 if ( ( nDestPixelWidth
!= nSourcePixelWidth
) || ( nDestPixelHeight
!= nSourcePixelHeight
) )
578 ImplApplyBitmapScaling( rGraphic
, nDestPixelWidth
, nDestPixelHeight
);
582 void ImplApplyFilterData( ::Graphic
& rGraphic
, uno::Sequence
< beans::PropertyValue
>& rFilterData
)
584 /* this method applies following attributes to the graphic, in the first step the
585 cropping area (logical size in 100thmm) is applied, in the second step the resolution
586 is applied, in the third step the graphic is scaled to the corresponding pixelsize.
587 if a parameter value is zero or not available the corresponding step will be skipped */
589 sal_Int32 nPixelWidth
= 0;
590 sal_Int32 nPixelHeight
= 0;
591 sal_Int32 nImageResolution
= 0;
592 awt::Size
aLogicalSize( 0, 0 );
593 text::GraphicCrop
aCropLogic( 0, 0, 0, 0 );
594 bool bRemoveCropArea
= true;
596 for( sal_Int32 i
= 0; i
< rFilterData
.getLength(); ++i
)
598 const OUString
aName( rFilterData
[ i
].Name
);
599 const uno::Any
aValue( rFilterData
[ i
].Value
);
601 if (aName
== "PixelWidth")
602 aValue
>>= nPixelWidth
;
603 else if (aName
== "PixelHeight")
604 aValue
>>= nPixelHeight
;
605 else if (aName
== "LogicalSize")
606 aValue
>>= aLogicalSize
;
607 else if (aName
== "GraphicCropLogic")
608 aValue
>>= aCropLogic
;
609 else if (aName
== "RemoveCropArea")
610 aValue
>>= bRemoveCropArea
;
611 else if (aName
== "ImageResolution")
612 aValue
>>= nImageResolution
;
614 if ( rGraphic
.GetType() == GRAPHIC_BITMAP
)
616 if(rGraphic
.getSvgData().get())
618 // embedded Svg, no need to scale. Also no method to apply crop data currently
622 Rectangle
aCropPixel( Point( 0, 0 ), rGraphic
.GetSizePixel() );
623 ImplCalculateCropRect( rGraphic
, aCropLogic
, aCropPixel
);
624 if ( bRemoveCropArea
)
626 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
627 aBmpEx
.Crop( aCropPixel
);
630 Size
aVisiblePixelSize( bRemoveCropArea
? rGraphic
.GetSizePixel() : aCropPixel
.GetSize() );
631 ImplApplyBitmapResolution( rGraphic
, nImageResolution
, aVisiblePixelSize
, aLogicalSize
);
632 ImplApplyBitmapScaling( rGraphic
, nPixelWidth
, nPixelHeight
);
635 else if ( ( rGraphic
.GetType() == GRAPHIC_GDIMETAFILE
) && nImageResolution
)
637 ScopedVclPtrInstance
< VirtualDevice
> aDummyVDev
;
638 GDIMetaFile
aMtf( rGraphic
.GetGDIMetaFile() );
639 Size
aMtfSize( OutputDevice::LogicToLogic( aMtf
.GetPrefSize(), aMtf
.GetPrefMapMode(), MAP_100TH_MM
) );
640 if ( aMtfSize
.Width() && aMtfSize
.Height() )
642 MapMode
aNewMapMode( MAP_100TH_MM
);
643 aNewMapMode
.SetScaleX( static_cast< double >( aLogicalSize
.Width
) / static_cast< double >( aMtfSize
.Width() ) );
644 aNewMapMode
.SetScaleY( static_cast< double >( aLogicalSize
.Height
) / static_cast< double >( aMtfSize
.Height() ) );
645 aDummyVDev
->EnableOutput( false );
646 aDummyVDev
->SetMapMode( aNewMapMode
);
648 for( size_t i
= 0, nObjCount
= aMtf
.GetActionSize(); i
< nObjCount
; i
++ )
650 MetaAction
* pAction
= aMtf
.GetAction( i
);
651 switch( pAction
->GetType() )
653 // only optimizing common bitmap actions:
654 case( MetaActionType::MAPMODE
):
656 const_cast< MetaAction
* >( pAction
)->Execute( aDummyVDev
.get() );
659 case( MetaActionType::PUSH
):
661 const MetaPushAction
* pA
= static_cast<const MetaPushAction
*>(pAction
);
662 aDummyVDev
->Push( pA
->GetFlags() );
665 case( MetaActionType::POP
):
670 case( MetaActionType::BMPSCALE
):
671 case( MetaActionType::BMPEXSCALE
):
676 if ( pAction
->GetType() == MetaActionType::BMPSCALE
)
678 MetaBmpScaleAction
* pScaleAction
= dynamic_cast< MetaBmpScaleAction
* >( pAction
);
679 aBmpEx
= pScaleAction
->GetBitmap();
680 aPos
= pScaleAction
->GetPoint();
681 aSize
= pScaleAction
->GetSize();
685 MetaBmpExScaleAction
* pScaleAction
= dynamic_cast< MetaBmpExScaleAction
* >( pAction
);
686 aBmpEx
= pScaleAction
->GetBitmapEx();
687 aPos
= pScaleAction
->GetPoint();
688 aSize
= pScaleAction
->GetSize();
690 ::Graphic
aGraphic( aBmpEx
);
691 const Size
aSize100thmm( aDummyVDev
->LogicToPixel( aSize
) );
692 Size
aSize100thmm2( aDummyVDev
->PixelToLogic( aSize100thmm
, MAP_100TH_MM
) );
694 ImplApplyBitmapResolution( aGraphic
, nImageResolution
,
695 aGraphic
.GetSizePixel(), awt::Size( aSize100thmm2
.Width(), aSize100thmm2
.Height() ) );
697 MetaAction
* pNewAction
;
698 if ( pAction
->GetType() == MetaActionType::BMPSCALE
)
699 pNewAction
= new MetaBmpScaleAction ( aPos
, aSize
, aGraphic
.GetBitmap() );
701 pNewAction
= new MetaBmpExScaleAction( aPos
, aSize
, aGraphic
.GetBitmapEx() );
703 MetaAction
* pDeleteAction
= aMtf
.ReplaceAction( pNewAction
, i
);
705 pDeleteAction
->Delete();
709 case( MetaActionType::BMP
):
710 case( MetaActionType::BMPSCALEPART
):
711 case( MetaActionType::BMPEX
):
712 case( MetaActionType::BMPEXSCALEPART
):
713 case( MetaActionType::MASK
):
714 case( MetaActionType::MASKSCALE
):
725 void SAL_CALL
GraphicProvider::storeGraphic( const uno::Reference
< ::graphic::XGraphic
>& rxGraphic
, const uno::Sequence
< beans::PropertyValue
>& rMediaProperties
)
726 throw ( io::IOException
, lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
730 boost::scoped_ptr
<SvStream
> pOStm
;
734 for( i
= 0; ( i
< rMediaProperties
.getLength() ) && !pOStm
; ++i
)
736 const OUString
aName( rMediaProperties
[ i
].Name
);
737 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
744 pOStm
.reset(::utl::UcbStreamHelper::CreateStream( aURL
, StreamMode::WRITE
| StreamMode::TRUNC
));
747 else if (aName
== "OutputStream")
749 uno::Reference
< io::XStream
> xOStm
;
754 pOStm
.reset(::utl::UcbStreamHelper::CreateStream( xOStm
));
760 uno::Sequence
< beans::PropertyValue
> aFilterDataSeq
;
761 const char* pFilterShortName
= NULL
;
763 for( i
= 0; i
< rMediaProperties
.getLength(); ++i
)
765 const OUString
aName( rMediaProperties
[ i
].Name
);
766 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
768 if (aName
== "FilterData")
770 aValue
>>= aFilterDataSeq
;
772 else if (aName
== "MimeType")
776 aValue
>>= aMimeType
;
778 if (aMimeType
== MIMETYPE_BMP
)
779 pFilterShortName
= "bmp";
780 else if (aMimeType
== MIMETYPE_EPS
)
781 pFilterShortName
= "eps";
782 else if (aMimeType
== MIMETYPE_GIF
)
783 pFilterShortName
= "gif";
784 else if (aMimeType
== MIMETYPE_JPG
)
785 pFilterShortName
= "jpg";
786 else if (aMimeType
== MIMETYPE_MET
)
787 pFilterShortName
= "met";
788 else if (aMimeType
== MIMETYPE_PNG
)
789 pFilterShortName
= "png";
790 else if (aMimeType
== MIMETYPE_PCT
)
791 pFilterShortName
= "pct";
792 else if (aMimeType
== MIMETYPE_PBM
)
793 pFilterShortName
= "pbm";
794 else if (aMimeType
== MIMETYPE_PGM
)
795 pFilterShortName
= "pgm";
796 else if (aMimeType
== MIMETYPE_PPM
)
797 pFilterShortName
= "ppm";
798 else if (aMimeType
== MIMETYPE_RAS
)
799 pFilterShortName
= "ras";
800 else if (aMimeType
== MIMETYPE_SVM
)
801 pFilterShortName
= "svm";
802 else if (aMimeType
== MIMETYPE_TIF
)
803 pFilterShortName
= "tif";
804 else if (aMimeType
== MIMETYPE_EMF
)
805 pFilterShortName
= "emf";
806 else if (aMimeType
== MIMETYPE_WMF
)
807 pFilterShortName
= "wmf";
808 else if (aMimeType
== MIMETYPE_XPM
)
809 pFilterShortName
= "xpm";
810 else if (aMimeType
== MIMETYPE_SVG
)
811 pFilterShortName
= "svg";
812 else if (aMimeType
== MIMETYPE_VCLGRAPHIC
)
813 pFilterShortName
= MIMETYPE_VCLGRAPHIC
;
817 if( pFilterShortName
)
819 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
822 const uno::Reference
< XInterface
> xIFace( rxGraphic
, uno::UNO_QUERY
);
823 const ::Graphic
* pGraphic
= ::unographic::Graphic::getImplementation( xIFace
);
825 if( pGraphic
&& ( pGraphic
->GetType() != GRAPHIC_NONE
) )
827 ::Graphic
aGraphic( *pGraphic
);
828 ImplApplyFilterData( aGraphic
, aFilterDataSeq
);
830 /* sj: using a temporary memory stream, because some graphic filters are seeking behind
831 stream end (which leads to an invalid argument exception then). */
832 SvMemoryStream aMemStrm
;
833 aMemStrm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
834 if( 0 == strcmp( pFilterShortName
, MIMETYPE_VCLGRAPHIC
) )
835 WriteGraphic( aMemStrm
, aGraphic
);
838 rFilter
.ExportGraphic( aGraphic
, aPath
, aMemStrm
,
839 rFilter
.GetExportFormatNumberForShortName( OUString::createFromAscii( pFilterShortName
) ),
840 ( aFilterDataSeq
.getLength() ? &aFilterDataSeq
: NULL
) );
842 aMemStrm
.Seek( STREAM_SEEK_TO_END
);
843 pOStm
->Write( aMemStrm
.GetData(), aMemStrm
.Tell() );
852 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
853 com_sun_star_comp_graphic_GraphicProvider_get_implementation(
854 css::uno::XComponentContext
*,
855 css::uno::Sequence
<css::uno::Any
> const &)
857 return cppu::acquire(new GraphicProvider
);
860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */