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 <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 <com/sun/star/io/XStream.hpp>
35 #include <com/sun/star/text/GraphicCrop.hpp>
36 #include <comphelper/servicehelper.hxx>
38 #include "descriptor.hxx"
39 #include "graphic.hxx"
40 #include <svtools/grfmgr.hxx>
41 #include "provider.hxx"
42 #include <vcl/dibtools.hxx>
44 using namespace com::sun::star
;
46 namespace unographic
{
48 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
50 // -------------------
51 // - GraphicProvider -
52 // -------------------
54 uno::Reference
< uno::XInterface
> SAL_CALL
GraphicProvider_CreateInstance( const uno::Reference
< lang::XMultiServiceFactory
>& )
56 return (static_cast< ::cppu::OWeakObject
* >(new GraphicProvider
));
59 GraphicProvider::GraphicProvider()
63 // ------------------------------------------------------------------------------
65 GraphicProvider::~GraphicProvider()
69 // ------------------------------------------------------------------------------
71 OUString
GraphicProvider::getImplementationName_Static()
74 return OUString( "com.sun.star.comp.graphic.GraphicProvider" );
77 // ------------------------------------------------------------------------------
79 uno::Sequence
< OUString
> GraphicProvider::getSupportedServiceNames_Static()
82 uno::Sequence
< OUString
> aSeq( 1 );
84 aSeq
.getArray()[ 0 ] = "com.sun.star.graphic.GraphicProvider";
89 // ------------------------------------------------------------------------------
91 OUString SAL_CALL
GraphicProvider::getImplementationName()
92 throw( uno::RuntimeException
)
94 return getImplementationName_Static();
97 // ------------------------------------------------------------------------------
99 sal_Bool SAL_CALL
GraphicProvider::supportsService( const OUString
& ServiceName
)
100 throw( uno::RuntimeException
)
102 uno::Sequence
< OUString
> aSNL( getSupportedServiceNames() );
103 const OUString
* pArray
= aSNL
.getConstArray();
105 for( int i
= 0; i
< aSNL
.getLength(); i
++ )
106 if( pArray
[i
] == ServiceName
)
112 // ------------------------------------------------------------------------------
114 uno::Sequence
< OUString
> SAL_CALL
GraphicProvider::getSupportedServiceNames()
115 throw( uno::RuntimeException
)
117 return getSupportedServiceNames_Static();
120 // ------------------------------------------------------------------------------
122 uno::Sequence
< uno::Type
> SAL_CALL
GraphicProvider::getTypes()
123 throw(uno::RuntimeException
)
125 uno::Sequence
< uno::Type
> aTypes( 3 );
126 uno::Type
* pTypes
= aTypes
.getArray();
128 *pTypes
++ = ::getCppuType((const uno::Reference
< lang::XServiceInfo
>*)0);
129 *pTypes
++ = ::getCppuType((const uno::Reference
< lang::XTypeProvider
>*)0);
130 *pTypes
++ = ::getCppuType((const uno::Reference
< graphic::XGraphicProvider
>*)0);
137 class theGraphicProviderUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theGraphicProviderUnoTunnelId
> {};
140 uno::Sequence
< sal_Int8
> SAL_CALL
GraphicProvider::getImplementationId()
141 throw(uno::RuntimeException
)
143 return theGraphicProviderUnoTunnelId::get().getSeq();
146 // ------------------------------------------------------------------------------
148 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadGraphicObject( const OUString
& rResourceURL
) const
150 uno::Reference
< ::graphic::XGraphic
> xRet
;
151 if( rResourceURL
.startsWith( UNO_NAME_GRAPHOBJ_URLPREFIX
) )
153 // graphic manager url
154 OUString
aTmpStr( rResourceURL
.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX
) - 1 ) );
155 OString
aUniqueID(OUStringToOString(aTmpStr
,
156 RTL_TEXTENCODING_UTF8
));
157 GraphicObject
aGrafObj(aUniqueID
);
158 // I don't call aGrafObj.GetXGraphic because it will call us back
159 // into implLoadMemory ( with "private:memorygraphic" test )
160 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
161 pUnoGraphic
->init( aGrafObj
.GetGraphic() );
167 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadMemory( const OUString
& rResourceURL
) const
169 uno::Reference
< ::graphic::XGraphic
> xRet
;
170 sal_Int32 nIndex
= 0;
172 if( rResourceURL
.getToken( 0, '/', nIndex
).equalsAscii( "private:memorygraphic" ) )
174 sal_Int64 nGraphicAddress
= rResourceURL
.getToken( 0, '/', nIndex
).toInt64();
176 if( nGraphicAddress
)
178 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
180 pUnoGraphic
->init( *reinterpret_cast< ::Graphic
* >( nGraphicAddress
) );
188 // ------------------------------------------------------------------------------
190 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadRepositoryImage( const OUString
& rResourceURL
) const
192 uno::Reference
< ::graphic::XGraphic
> xRet
;
193 sal_Int32 nIndex
= 0;
195 if( rResourceURL
.getToken( 0, '/', nIndex
).equalsAscii( "private:graphicrepository" ) )
197 OUString
sPathName( rResourceURL
.copy( nIndex
) );
199 if ( ::vcl::ImageRepository::loadImage( sPathName
, aBitmap
, false ) )
201 Image
aImage( aBitmap
);
202 xRet
= aImage
.GetXGraphic();
209 // ------------------------------------------------------------------------------
211 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadStandardImage( const OUString
& rResourceURL
) const
213 uno::Reference
< ::graphic::XGraphic
> xRet
;
214 sal_Int32 nIndex
= 0;
216 if( rResourceURL
.getToken( 0, '/', nIndex
).equalsAscii( "private:standardimage" ) )
218 OUString
sImageName( rResourceURL
.copy( nIndex
) );
219 if ( sImageName
== "info" )
221 xRet
= InfoBox::GetStandardImage().GetXGraphic();
223 else if ( sImageName
== "warning" )
225 xRet
= WarningBox::GetStandardImage().GetXGraphic();
227 else if ( sImageName
== "error" )
229 xRet
= ErrorBox::GetStandardImage().GetXGraphic();
231 else if ( sImageName
== "query" )
233 xRet
= QueryBox::GetStandardImage().GetXGraphic();
239 // ------------------------------------------------------------------------------
241 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadBitmap( const uno::Reference
< awt::XBitmap
>& xBtm
) const
243 uno::Reference
< ::graphic::XGraphic
> xRet
;
244 uno::Sequence
< sal_Int8
> aBmpSeq( xBtm
->getDIB() );
245 uno::Sequence
< sal_Int8
> aMaskSeq( xBtm
->getMaskDIB() );
246 SvMemoryStream
aBmpStream( aBmpSeq
.getArray(), aBmpSeq
.getLength(), STREAM_READ
);
250 ReadDIB(aBmp
, aBmpStream
, true);
252 if( aMaskSeq
.getLength() )
254 SvMemoryStream
aMaskStream( aMaskSeq
.getArray(), aMaskSeq
.getLength(), STREAM_READ
);
257 ReadDIB(aMask
, aMaskStream
, true);
258 aBmpEx
= BitmapEx( aBmp
, aMask
);
261 aBmpEx
= BitmapEx( aBmp
);
263 if( !aBmpEx
.IsEmpty() )
265 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
267 pUnoGraphic
->init( aBmpEx
);
273 // ------------------------------------------------------------------------------
275 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadResource( const OUString
& rResourceURL
) const
277 uno::Reference
< ::graphic::XGraphic
> xRet
;
278 sal_Int32 nIndex
= 0;
280 if( rResourceURL
.getToken( 0, '/', nIndex
).equalsAscii( "private:resource" ) )
282 OString
aResMgrName(OUStringToOString(
283 rResourceURL
.getToken(0, '/', nIndex
), RTL_TEXTENCODING_ASCII_US
));
285 ResMgr
* pResMgr
= ResMgr::CreateResMgr( aResMgrName
.getStr(), Application::GetSettings().GetUILanguageTag() );
289 const OUString
aResourceType( rResourceURL
.getToken( 0, '/', nIndex
) );
290 const ResId
aResId( rResourceURL
.getToken( 0, '/', nIndex
).toInt32(), *pResMgr
);
292 if( !aResourceType
.isEmpty() )
296 if( aResourceType
.equalsAscii( "bitmap" ) ||
297 aResourceType
.equalsAscii( "bitmapex" ) )
299 aResId
.SetRT( RSC_BITMAP
);
301 if( pResMgr
->IsAvailable( aResId
) )
303 aBmpEx
= BitmapEx( aResId
);
306 else if( aResourceType
.equalsAscii( "image" ) )
308 aResId
.SetRT( RSC_IMAGE
);
310 if( pResMgr
->IsAvailable( aResId
) )
312 const Image
aImage( aResId
);
313 aBmpEx
= aImage
.GetBitmapEx();
316 else if( aResourceType
.equalsAscii( "imagelist" ) )
318 aResId
.SetRT( RSC_IMAGELIST
);
320 if( pResMgr
->IsAvailable( aResId
) )
322 const ImageList
aImageList( aResId
);
323 sal_Int32 nImageId
= ( nIndex
> -1 ) ? rResourceURL
.getToken( 0, '/', nIndex
).toInt32() : 0;
327 const Image
aImage( aImageList
.GetImage( sal::static_int_cast
< sal_uInt16
>(nImageId
) ) );
328 aBmpEx
= aImage
.GetBitmapEx();
332 aBmpEx
= aImageList
.GetAsHorizontalStrip();
337 if( !aBmpEx
.IsEmpty() )
339 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
341 pUnoGraphic
->init( aBmpEx
);
353 // ------------------------------------------------------------------------------
355 uno::Reference
< beans::XPropertySet
> SAL_CALL
GraphicProvider::queryGraphicDescriptor( const uno::Sequence
< beans::PropertyValue
>& rMediaProperties
)
356 throw ( io::IOException
, lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
)
358 uno::Reference
< beans::XPropertySet
> xRet
;
361 uno::Reference
< io::XInputStream
> xIStm
;
362 uno::Reference
< awt::XBitmap
>xBtm
;
364 for( sal_Int32 i
= 0; ( i
< rMediaProperties
.getLength() ) && !xRet
.is(); ++i
)
366 const OUString
aName( rMediaProperties
[ i
].Name
);
367 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
373 else if (aName
== "InputStream")
377 else if (aName
== "Bitmap")
387 GraphicDescriptor
* pDescriptor
= new GraphicDescriptor
;
388 pDescriptor
->init( xIStm
, aURL
);
391 else if( !aURL
.isEmpty() )
393 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadMemory( aURL
) );
395 xGraphic
= implLoadResource( aURL
);
397 xGraphic
= implLoadGraphicObject( aURL
);
399 if ( !xGraphic
.is() )
400 xGraphic
= implLoadRepositoryImage( aURL
);
402 if ( !xGraphic
.is() )
403 xGraphic
= implLoadStandardImage( aURL
);
407 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
411 GraphicDescriptor
* pDescriptor
= new GraphicDescriptor
;
412 pDescriptor
->init( aURL
);
418 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadBitmap( xBtm
) );
420 xRet
= uno::Reference
< beans::XPropertySet
>( xGraphic
, uno::UNO_QUERY
);
426 // ------------------------------------------------------------------------------
428 uno::Reference
< ::graphic::XGraphic
> SAL_CALL
GraphicProvider::queryGraphic( const uno::Sequence
< ::beans::PropertyValue
>& rMediaProperties
)
429 throw ( io::IOException
, lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
)
431 uno::Reference
< ::graphic::XGraphic
> xRet
;
433 SvStream
* pIStm
= NULL
;
435 uno::Reference
< io::XInputStream
> xIStm
;
436 uno::Reference
< awt::XBitmap
>xBtm
;
438 uno::Sequence
< ::beans::PropertyValue
> aFilterData
;
440 for( sal_Int32 i
= 0; ( i
< rMediaProperties
.getLength() ) && !pIStm
&& !xRet
.is(); ++i
)
442 const OUString
aName( rMediaProperties
[ i
].Name
);
443 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
451 else if (aName
== "InputStream")
455 else if (aName
== "Bitmap")
459 else if (aName
== "FilterData")
461 aValue
>>= aFilterData
;
465 // Check for the goal width and height if they are defined
466 sal_uInt16 nExtWidth
= 0;
467 sal_uInt16 nExtHeight
= 0;
468 sal_uInt16 nExtMapMode
= 0;
469 for( sal_Int32 i
= 0; i
< aFilterData
.getLength(); ++i
)
471 const OUString
aName( aFilterData
[ i
].Name
);
472 const uno::Any
aValue( aFilterData
[ i
].Value
);
474 if (aName
== "ExternalWidth")
476 aValue
>>= nExtWidth
;
478 else if (aName
== "ExternalHeight")
480 aValue
>>= nExtHeight
;
482 else if (aName
== "ExternalMapMode")
484 aValue
>>= nExtMapMode
;
492 pIStm
= ::utl::UcbStreamHelper::CreateStream( xIStm
);
494 else if( !aPath
.isEmpty() )
496 xRet
= implLoadMemory( aPath
);
499 xRet
= implLoadGraphicObject( aPath
);
502 xRet
= implLoadResource( aPath
);
505 xRet
= implLoadRepositoryImage( aPath
);
508 xRet
= implLoadStandardImage( aPath
);
511 pIStm
= ::utl::UcbStreamHelper::CreateStream( aPath
, STREAM_READ
);
515 xRet
= implLoadBitmap( xBtm
);
520 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
523 ::Graphic aVCLGraphic
;
525 // Define APM Header if goal height and width are defined
526 WMF_EXTERNALHEADER aExtHeader
;
527 aExtHeader
.xExt
= nExtWidth
;
528 aExtHeader
.yExt
= nExtHeight
;
529 aExtHeader
.mapMode
= nExtMapMode
;
530 WMF_EXTERNALHEADER
*pExtHeader
= NULL
;
531 if ( nExtMapMode
> 0 )
532 pExtHeader
= &aExtHeader
;
534 if( ( rFilter
.ImportGraphic( aVCLGraphic
, aPath
, *pIStm
,
535 GRFILTER_FORMAT_DONTKNOW
, NULL
, 0, pExtHeader
) == GRFILTER_OK
) &&
536 ( aVCLGraphic
.GetType() != GRAPHIC_NONE
) )
538 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
540 pUnoGraphic
->init( aVCLGraphic
);
551 void ImplCalculateCropRect( ::Graphic
& rGraphic
, const text::GraphicCrop
& rGraphicCropLogic
, Rectangle
& rGraphicCropPixel
)
553 if ( rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
)
555 Size
aSourceSizePixel( rGraphic
.GetSizePixel() );
556 if ( aSourceSizePixel
.Width() && aSourceSizePixel
.Height() )
558 if ( rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
)
560 Size
aSize100thMM( 0, 0 );
561 if( rGraphic
.GetPrefMapMode().GetMapUnit() != MAP_PIXEL
)
563 aSize100thMM
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode(), MAP_100TH_MM
);
567 aSize100thMM
= Application::GetDefaultDevice()->PixelToLogic( rGraphic
.GetPrefSize(), MAP_100TH_MM
);
569 if ( aSize100thMM
.Width() && aSize100thMM
.Height() )
571 double fSourceSizePixelWidth
= static_cast<double>(aSourceSizePixel
.Width());
572 double fSourceSizePixelHeight
= static_cast<double>(aSourceSizePixel
.Height());
573 rGraphicCropPixel
.Left() = static_cast< sal_Int32
>((fSourceSizePixelWidth
* rGraphicCropLogic
.Left
) / aSize100thMM
.Width());
574 rGraphicCropPixel
.Top() = static_cast< sal_Int32
>((fSourceSizePixelHeight
* rGraphicCropLogic
.Top
) / aSize100thMM
.Height());
575 rGraphicCropPixel
.Right() = static_cast< sal_Int32
>(( fSourceSizePixelWidth
* ( aSize100thMM
.Width() - rGraphicCropLogic
.Right
) ) / aSize100thMM
.Width() );
576 rGraphicCropPixel
.Bottom() = static_cast< sal_Int32
>(( fSourceSizePixelHeight
* ( aSize100thMM
.Height() - rGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height() );
583 void ImplApplyBitmapScaling( ::Graphic
& rGraphic
, sal_Int32 nPixelWidth
, sal_Int32 nPixelHeight
)
585 if ( nPixelWidth
&& nPixelHeight
)
587 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
588 MapMode
aPrefMapMode( aBmpEx
.GetPrefMapMode() );
589 Size
aPrefSize( aBmpEx
.GetPrefSize() );
590 aBmpEx
.Scale( Size( nPixelWidth
, nPixelHeight
) );
591 aBmpEx
.SetPrefMapMode( aPrefMapMode
);
592 aBmpEx
.SetPrefSize( aPrefSize
);
597 void ImplApplyBitmapResolution( ::Graphic
& rGraphic
, sal_Int32 nImageResolution
, const Size
& rVisiblePixelSize
, const awt::Size
& rLogicalSize
)
599 if ( nImageResolution
&& rLogicalSize
.Width
&& rLogicalSize
.Height
)
601 const double fImageResolution
= static_cast<double>( nImageResolution
);
602 const double fSourceDPIX
= ( static_cast<double>(rVisiblePixelSize
.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Width
);
603 const double fSourceDPIY
= ( static_cast<double>(rVisiblePixelSize
.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Height
);
604 const sal_Int32
nSourcePixelWidth( rGraphic
.GetSizePixel().Width() );
605 const sal_Int32
nSourcePixelHeight( rGraphic
.GetSizePixel().Height() );
606 const double fSourcePixelWidth
= static_cast<double>( nSourcePixelWidth
);
607 const double fSourcePixelHeight
= static_cast<double>( nSourcePixelHeight
);
609 sal_Int32 nDestPixelWidth
= nSourcePixelWidth
;
610 sal_Int32 nDestPixelHeight
= nSourcePixelHeight
;
612 // check, if the bitmap DPI exceeds the maximum DPI
613 if( fSourceDPIX
> fImageResolution
)
615 nDestPixelWidth
= static_cast<sal_Int32
>(( fSourcePixelWidth
* fImageResolution
) / fSourceDPIX
);
616 if ( !nDestPixelWidth
|| ( nDestPixelWidth
> nSourcePixelWidth
) )
617 nDestPixelWidth
= nSourcePixelWidth
;
619 if ( fSourceDPIY
> fImageResolution
)
621 nDestPixelHeight
= static_cast<sal_Int32
>(( fSourcePixelHeight
* fImageResolution
) / fSourceDPIY
);
622 if ( !nDestPixelHeight
|| ( nDestPixelHeight
> nSourcePixelHeight
) )
623 nDestPixelHeight
= nSourcePixelHeight
;
625 if ( ( nDestPixelWidth
!= nSourcePixelWidth
) || ( nDestPixelHeight
!= nSourcePixelHeight
) )
626 ImplApplyBitmapScaling( rGraphic
, nDestPixelWidth
, nDestPixelHeight
);
630 void ImplApplyFilterData( ::Graphic
& rGraphic
, uno::Sequence
< beans::PropertyValue
>& rFilterData
)
632 /* this method applies following attributes to the graphic, in the first step the
633 cropping area (logical size in 100thmm) is applied, in the second step the resolution
634 is applied, in the third step the graphic is scaled to the corresponding pixelsize.
635 if a parameter value is zero or not available the corresponding step will be skipped */
637 sal_Int32 nPixelWidth
= 0;
638 sal_Int32 nPixelHeight
= 0;
639 sal_Int32 nImageResolution
= 0;
640 awt::Size
aLogicalSize( 0, 0 );
641 text::GraphicCrop
aCropLogic( 0, 0, 0, 0 );
642 sal_Bool bRemoveCropArea
= sal_True
;
644 for( sal_Int32 i
= 0; i
< rFilterData
.getLength(); ++i
)
646 const OUString
aName( rFilterData
[ i
].Name
);
647 const uno::Any
aValue( rFilterData
[ i
].Value
);
649 if (aName
== "PixelWidth")
650 aValue
>>= nPixelWidth
;
651 else if (aName
== "PixelHeight")
652 aValue
>>= nPixelHeight
;
653 else if (aName
== "LogicalSize")
654 aValue
>>= aLogicalSize
;
655 else if (aName
== "GraphicCropLogic")
656 aValue
>>= aCropLogic
;
657 else if (aName
== "RemoveCropArea")
658 aValue
>>= bRemoveCropArea
;
659 else if (aName
== "ImageResolution")
660 aValue
>>= nImageResolution
;
662 if ( rGraphic
.GetType() == GRAPHIC_BITMAP
)
664 if(rGraphic
.getSvgData().get())
666 // embedded Svg, no need to scale. Also no method to apply crop data currently
670 Rectangle
aCropPixel( Point( 0, 0 ), rGraphic
.GetSizePixel() );
671 ImplCalculateCropRect( rGraphic
, aCropLogic
, aCropPixel
);
672 if ( bRemoveCropArea
)
674 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
675 aBmpEx
.Crop( aCropPixel
);
678 Size
aVisiblePixelSize( bRemoveCropArea
? rGraphic
.GetSizePixel() : aCropPixel
.GetSize() );
679 ImplApplyBitmapResolution( rGraphic
, nImageResolution
, aVisiblePixelSize
, aLogicalSize
);
680 ImplApplyBitmapScaling( rGraphic
, nPixelWidth
, nPixelHeight
);
683 else if ( ( rGraphic
.GetType() == GRAPHIC_GDIMETAFILE
) && nImageResolution
)
685 VirtualDevice aDummyVDev
;
686 GDIMetaFile
aMtf( rGraphic
.GetGDIMetaFile() );
687 Size
aMtfSize( aDummyVDev
.LogicToLogic( aMtf
.GetPrefSize(), aMtf
.GetPrefMapMode(), MAP_100TH_MM
) );
688 if ( aMtfSize
.Width() && aMtfSize
.Height() )
690 MapMode
aNewMapMode( MAP_100TH_MM
);
691 aNewMapMode
.SetScaleX( static_cast< double >( aLogicalSize
.Width
) / static_cast< double >( aMtfSize
.Width() ) );
692 aNewMapMode
.SetScaleY( static_cast< double >( aLogicalSize
.Height
) / static_cast< double >( aMtfSize
.Height() ) );
693 aDummyVDev
.EnableOutput( sal_False
);
694 aDummyVDev
.SetMapMode( aNewMapMode
);
696 for( size_t i
= 0, nObjCount
= aMtf
.GetActionSize(); i
< nObjCount
; i
++ )
698 MetaAction
* pAction
= aMtf
.GetAction( i
);
699 switch( pAction
->GetType() )
701 // only optimizing common bitmap actions:
702 case( META_MAPMODE_ACTION
):
704 const_cast< MetaAction
* >( pAction
)->Execute( &aDummyVDev
);
707 case( META_PUSH_ACTION
):
709 const MetaPushAction
* pA
= (const MetaPushAction
*)pAction
;
710 aDummyVDev
.Push( pA
->GetFlags() );
713 case( META_POP_ACTION
):
718 case( META_BMPSCALE_ACTION
):
719 case( META_BMPEXSCALE_ACTION
):
724 if ( pAction
->GetType() == META_BMPSCALE_ACTION
)
726 MetaBmpScaleAction
* pScaleAction
= dynamic_cast< MetaBmpScaleAction
* >( pAction
);
727 aBmpEx
= pScaleAction
->GetBitmap();
728 aPos
= pScaleAction
->GetPoint();
729 aSize
= pScaleAction
->GetSize();
733 MetaBmpExScaleAction
* pScaleAction
= dynamic_cast< MetaBmpExScaleAction
* >( pAction
);
734 aBmpEx
= pScaleAction
->GetBitmapEx();
735 aPos
= pScaleAction
->GetPoint();
736 aSize
= pScaleAction
->GetSize();
738 ::Graphic
aGraphic( aBmpEx
);
739 const Size
aSize100thmm( aDummyVDev
.LogicToPixel( aSize
) );
740 Size
aSize100thmm2( aDummyVDev
.PixelToLogic( aSize100thmm
, MAP_100TH_MM
) );
742 ImplApplyBitmapResolution( aGraphic
, nImageResolution
,
743 aGraphic
.GetSizePixel(), awt::Size( aSize100thmm2
.Width(), aSize100thmm2
.Height() ) );
745 MetaAction
* pNewAction
;
746 if ( pAction
->GetType() == META_BMPSCALE_ACTION
)
747 pNewAction
= new MetaBmpScaleAction ( aPos
, aSize
, aGraphic
.GetBitmap() );
749 pNewAction
= new MetaBmpExScaleAction( aPos
, aSize
, aGraphic
.GetBitmapEx() );
751 MetaAction
* pDeleteAction
= aMtf
.ReplaceAction( pNewAction
, i
);
753 pDeleteAction
->Delete();
757 case( META_BMP_ACTION
):
758 case( META_BMPSCALEPART_ACTION
):
759 case( META_BMPEX_ACTION
):
760 case( META_BMPEXSCALEPART_ACTION
):
761 case( META_MASK_ACTION
):
762 case( META_MASKSCALE_ACTION
):
771 // ------------------------------------------------------------------------------
773 void SAL_CALL
GraphicProvider::storeGraphic( const uno::Reference
< ::graphic::XGraphic
>& rxGraphic
, const uno::Sequence
< beans::PropertyValue
>& rMediaProperties
)
774 throw ( io::IOException
, lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
)
778 SvStream
* pOStm
= NULL
;
782 for( i
= 0; ( i
< rMediaProperties
.getLength() ) && !pOStm
; ++i
)
784 const OUString
aName( rMediaProperties
[ i
].Name
);
785 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
792 pOStm
= ::utl::UcbStreamHelper::CreateStream( aURL
, STREAM_WRITE
| STREAM_TRUNC
);
795 else if (aName
== "OutputStream")
797 uno::Reference
< io::XStream
> xOStm
;
802 pOStm
= ::utl::UcbStreamHelper::CreateStream( xOStm
);
808 uno::Sequence
< beans::PropertyValue
> aFilterDataSeq
;
809 const char* pFilterShortName
= NULL
;
811 for( i
= 0; i
< rMediaProperties
.getLength(); ++i
)
813 const OUString
aName( rMediaProperties
[ i
].Name
);
814 const uno::Any
aValue( rMediaProperties
[ i
].Value
);
816 if (aName
== "FilterData")
818 aValue
>>= aFilterDataSeq
;
820 else if (aName
== "MimeType")
824 aValue
>>= aMimeType
;
826 if (aMimeType
== MIMETYPE_BMP
)
827 pFilterShortName
= "bmp";
828 else if (aMimeType
== MIMETYPE_EPS
)
829 pFilterShortName
= "eps";
830 else if (aMimeType
== MIMETYPE_GIF
)
831 pFilterShortName
= "gif";
832 else if (aMimeType
== MIMETYPE_JPG
)
833 pFilterShortName
= "jpg";
834 else if (aMimeType
== MIMETYPE_MET
)
835 pFilterShortName
= "met";
836 else if (aMimeType
== MIMETYPE_PNG
)
837 pFilterShortName
= "png";
838 else if (aMimeType
== MIMETYPE_PCT
)
839 pFilterShortName
= "pct";
840 else if (aMimeType
== MIMETYPE_PBM
)
841 pFilterShortName
= "pbm";
842 else if (aMimeType
== MIMETYPE_PGM
)
843 pFilterShortName
= "pgm";
844 else if (aMimeType
== MIMETYPE_PPM
)
845 pFilterShortName
= "ppm";
846 else if (aMimeType
== MIMETYPE_RAS
)
847 pFilterShortName
= "ras";
848 else if (aMimeType
== MIMETYPE_SVM
)
849 pFilterShortName
= "svm";
850 else if (aMimeType
== MIMETYPE_TIF
)
851 pFilterShortName
= "tif";
852 else if (aMimeType
== MIMETYPE_EMF
)
853 pFilterShortName
= "emf";
854 else if (aMimeType
== MIMETYPE_WMF
)
855 pFilterShortName
= "wmf";
856 else if (aMimeType
== MIMETYPE_XPM
)
857 pFilterShortName
= "xpm";
858 else if (aMimeType
== MIMETYPE_SVG
)
859 pFilterShortName
= "svg";
860 else if (aMimeType
== MIMETYPE_VCLGRAPHIC
)
861 pFilterShortName
= MIMETYPE_VCLGRAPHIC
;
865 if( pFilterShortName
)
867 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
870 const uno::Reference
< XInterface
> xIFace( rxGraphic
, uno::UNO_QUERY
);
871 const ::Graphic
* pGraphic
= ::unographic::Graphic::getImplementation( xIFace
);
873 if( pGraphic
&& ( pGraphic
->GetType() != GRAPHIC_NONE
) )
875 ::Graphic
aGraphic( *pGraphic
);
876 ImplApplyFilterData( aGraphic
, aFilterDataSeq
);
878 /* sj: using a temporary memory stream, because some graphic filters are seeking behind
879 stream end (which leads to an invalid argument exception then). */
880 SvMemoryStream aMemStrm
;
881 aMemStrm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
882 if( 0 == strcmp( pFilterShortName
, MIMETYPE_VCLGRAPHIC
) )
883 aMemStrm
<< aGraphic
;
886 rFilter
.ExportGraphic( aGraphic
, aPath
, aMemStrm
,
887 rFilter
.GetExportFormatNumberForShortName( OUString::createFromAscii( pFilterShortName
) ),
888 ( aFilterDataSeq
.getLength() ? &aFilterDataSeq
: NULL
) );
890 aMemStrm
.Seek( STREAM_SEEK_TO_END
);
891 pOStm
->Write( aMemStrm
.GetData(), aMemStrm
.Tell() );
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */