Bump version to 5.0-14
[LibreOffice.git] / svtools / source / graphic / provider.cxx
blob7a5bda77d24799a2d64dbc9ee6e92ca716946bbc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
52 namespace {
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";
81 return aSeq;
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();
94 return aTypes;
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() );
119 xRet = pUnoGraphic;
121 return xRet;
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 ) );
138 xRet = pUnoGraphic;
142 return xRet;
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 ) );
155 BitmapEx aBitmap;
156 if ( vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) )
158 Image aImage( aBitmap );
159 xRet = aImage.GetXGraphic();
162 return xRet;
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();
193 return xRet;
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 );
204 Bitmap aBmp;
205 BitmapEx aBmpEx;
207 ReadDIB(aBmp, aBmpStream, true);
209 if( aMaskSeq.getLength() )
211 SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), StreamMode::READ );
212 Bitmap aMask;
214 ReadDIB(aMask, aMaskStream, true);
215 aBmpEx = BitmapEx( aBmp, aMask );
217 else
218 aBmpEx = BitmapEx( aBmp );
220 if( !aBmpEx.IsEmpty() )
222 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
224 pUnoGraphic->init( aBmpEx );
225 xRet = pUnoGraphic;
227 return xRet;
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() ));
244 if( pResMgr )
246 const OUString aResourceType( rResourceURL.getToken( 0, '/', nIndex ) );
247 const ResId aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr );
249 if( !aResourceType.isEmpty() )
251 BitmapEx aBmpEx;
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;
281 if( 0 < nImageId )
283 const Image aImage( aImageList.GetImage( sal::static_int_cast< sal_uInt16 >(nImageId) ) );
284 aBmpEx = aImage.GetBitmapEx();
286 else
288 aBmpEx = aImageList.GetAsHorizontalStrip();
293 if( !aBmpEx.IsEmpty() )
295 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
297 pUnoGraphic->init( aBmpEx );
298 xRet = pUnoGraphic;
304 return xRet;
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;
314 OUString aURL;
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 );
323 if (aName == "URL")
325 aValue >>= aURL;
327 else if (aName == "InputStream")
329 aValue >>= xIStm;
331 else if (aName == "Bitmap")
333 aValue >>= xBtm;
337 SolarMutexGuard g;
339 if( xIStm.is() )
341 unographic::GraphicDescriptor* pDescriptor = new unographic::GraphicDescriptor;
342 pDescriptor->init( xIStm, aURL );
343 xRet = pDescriptor;
345 else if( !aURL.isEmpty() )
347 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) );
348 if( !xGraphic.is() )
349 xGraphic = implLoadResource( aURL );
350 if( !xGraphic.is() )
351 xGraphic = implLoadGraphicObject( aURL );
353 if ( !xGraphic.is() )
354 xGraphic = implLoadRepositoryImage( aURL );
356 if ( !xGraphic.is() )
357 xGraphic = implLoadStandardImage( aURL );
359 if( xGraphic.is() )
361 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
363 else
365 unographic::GraphicDescriptor* pDescriptor = new unographic::GraphicDescriptor;
366 pDescriptor->init( aURL );
367 xRet = pDescriptor;
370 else if( xBtm.is() )
372 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) );
373 if( xGraphic.is() )
374 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
377 return xRet;
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;
386 OUString aPath;
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 );
399 if (aName == "URL")
401 OUString aURL;
402 aValue >>= aURL;
403 aPath = aURL;
405 else if (aName == "InputStream")
407 aValue >>= xIStm;
409 else if (aName == "Bitmap")
411 aValue >>= xBtm;
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;
442 SolarMutexGuard g;
444 if( xIStm.is() )
446 pIStm.reset(::utl::UcbStreamHelper::CreateStream( xIStm ));
448 else if( !aPath.isEmpty() )
450 xRet = implLoadMemory( aPath );
452 if( !xRet.is() )
453 xRet = implLoadGraphicObject( aPath );
455 if( !xRet.is() )
456 xRet = implLoadResource( aPath );
458 if ( !xRet.is() )
459 xRet = implLoadRepositoryImage( aPath );
461 if ( !xRet.is() )
462 xRet = implLoadStandardImage( aPath );
464 if( !xRet.is() )
465 pIStm.reset(::utl::UcbStreamHelper::CreateStream( aPath, StreamMode::READ ));
467 else if( xBtm.is() )
469 xRet = implLoadBitmap( xBtm );
472 if( pIStm )
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 );
495 xRet = pUnoGraphic;
500 return xRet;
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 );
517 else
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 );
545 rGraphic = aBmpEx;
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
620 else
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 );
628 rGraphic = aBmpEx;
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() );
657 break;
659 case( MetaActionType::PUSH ):
661 const MetaPushAction* pA = static_cast<const MetaPushAction*>(pAction);
662 aDummyVDev->Push( pA->GetFlags() );
663 break;
665 case( MetaActionType::POP ):
667 aDummyVDev->Pop();
668 break;
670 case( MetaActionType::BMPSCALE ):
671 case( MetaActionType::BMPEXSCALE ):
673 BitmapEx aBmpEx;
674 Point aPos;
675 Size aSize;
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();
683 else
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() );
700 else
701 pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() );
703 MetaAction* pDeleteAction = aMtf.ReplaceAction( pNewAction, i );
704 if(pDeleteAction)
705 pDeleteAction->Delete();
706 break;
708 default:
709 case( MetaActionType::BMP ):
710 case( MetaActionType::BMPSCALEPART ):
711 case( MetaActionType::BMPEX ):
712 case( MetaActionType::BMPEXSCALEPART ):
713 case( MetaActionType::MASK ):
714 case( MetaActionType::MASKSCALE ):
715 break;
718 rGraphic = aMtf;
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)
728 SolarMutexGuard g;
730 boost::scoped_ptr<SvStream> pOStm;
731 OUString aPath;
732 sal_Int32 i;
734 for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i )
736 const OUString aName( rMediaProperties[ i ].Name );
737 const uno::Any aValue( rMediaProperties[ i ].Value );
739 if (aName == "URL")
741 OUString aURL;
743 aValue >>= aURL;
744 pOStm.reset(::utl::UcbStreamHelper::CreateStream( aURL, StreamMode::WRITE | StreamMode::TRUNC ));
745 aPath = aURL;
747 else if (aName == "OutputStream")
749 uno::Reference< io::XStream > xOStm;
751 aValue >>= xOStm;
753 if( xOStm.is() )
754 pOStm.reset(::utl::UcbStreamHelper::CreateStream( xOStm ));
758 if( pOStm )
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")
774 OUString aMimeType;
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 );
836 else
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: */