GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / graphic / provider.cxx
blobcf5113b5c93fa279a29ad31e38b056e4d6118488
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 <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()
72 throw()
74 return OUString( "com.sun.star.comp.graphic.GraphicProvider" );
77 // ------------------------------------------------------------------------------
79 uno::Sequence< OUString > GraphicProvider::getSupportedServiceNames_Static()
80 throw()
82 uno::Sequence< OUString > aSeq( 1 );
84 aSeq.getArray()[ 0 ] = "com.sun.star.graphic.GraphicProvider";
86 return aSeq;
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 )
107 return true;
109 return false;
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);
132 return aTypes;
135 namespace
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() );
162 xRet = pUnoGraphic;
164 return xRet;
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 ) );
181 xRet = pUnoGraphic;
185 return xRet;
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 ) );
198 BitmapEx aBitmap;
199 if ( ::vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) )
201 Image aImage( aBitmap );
202 xRet = aImage.GetXGraphic();
205 return xRet;
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();
236 return xRet;
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 );
247 Bitmap aBmp;
248 BitmapEx aBmpEx;
250 ReadDIB(aBmp, aBmpStream, true);
252 if( aMaskSeq.getLength() )
254 SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), STREAM_READ );
255 Bitmap aMask;
257 ReadDIB(aMask, aMaskStream, true);
258 aBmpEx = BitmapEx( aBmp, aMask );
260 else
261 aBmpEx = BitmapEx( aBmp );
263 if( !aBmpEx.IsEmpty() )
265 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
267 pUnoGraphic->init( aBmpEx );
268 xRet = pUnoGraphic;
270 return xRet;
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() );
287 if( pResMgr )
289 const OUString aResourceType( rResourceURL.getToken( 0, '/', nIndex ) );
290 const ResId aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr );
292 if( !aResourceType.isEmpty() )
294 BitmapEx aBmpEx;
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;
325 if( 0 < nImageId )
327 const Image aImage( aImageList.GetImage( sal::static_int_cast< sal_uInt16 >(nImageId) ) );
328 aBmpEx = aImage.GetBitmapEx();
330 else
332 aBmpEx = aImageList.GetAsHorizontalStrip();
337 if( !aBmpEx.IsEmpty() )
339 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic;
341 pUnoGraphic->init( aBmpEx );
342 xRet = pUnoGraphic;
346 delete pResMgr;
350 return xRet;
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;
360 OUString aURL;
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 );
369 if (aName == "URL")
371 aValue >>= aURL;
373 else if (aName == "InputStream")
375 aValue >>= xIStm;
377 else if (aName == "Bitmap")
379 aValue >>= xBtm;
383 SolarMutexGuard g;
385 if( xIStm.is() )
387 GraphicDescriptor* pDescriptor = new GraphicDescriptor;
388 pDescriptor->init( xIStm, aURL );
389 xRet = pDescriptor;
391 else if( !aURL.isEmpty() )
393 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) );
394 if( !xGraphic.is() )
395 xGraphic = implLoadResource( aURL );
396 if( !xGraphic.is() )
397 xGraphic = implLoadGraphicObject( aURL );
399 if ( !xGraphic.is() )
400 xGraphic = implLoadRepositoryImage( aURL );
402 if ( !xGraphic.is() )
403 xGraphic = implLoadStandardImage( aURL );
405 if( xGraphic.is() )
407 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
409 else
411 GraphicDescriptor* pDescriptor = new GraphicDescriptor;
412 pDescriptor->init( aURL );
413 xRet = pDescriptor;
416 else if( xBtm.is() )
418 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) );
419 if( xGraphic.is() )
420 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY );
423 return xRet;
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;
432 OUString aPath;
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 );
445 if (aName == "URL")
447 OUString aURL;
448 aValue >>= aURL;
449 aPath = aURL;
451 else if (aName == "InputStream")
453 aValue >>= xIStm;
455 else if (aName == "Bitmap")
457 aValue >>= xBtm;
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;
488 SolarMutexGuard g;
490 if( xIStm.is() )
492 pIStm = ::utl::UcbStreamHelper::CreateStream( xIStm );
494 else if( !aPath.isEmpty() )
496 xRet = implLoadMemory( aPath );
498 if( !xRet.is() )
499 xRet = implLoadGraphicObject( aPath );
501 if( !xRet.is() )
502 xRet = implLoadResource( aPath );
504 if ( !xRet.is() )
505 xRet = implLoadRepositoryImage( aPath );
507 if ( !xRet.is() )
508 xRet = implLoadStandardImage( aPath );
510 if( !xRet.is() )
511 pIStm = ::utl::UcbStreamHelper::CreateStream( aPath, STREAM_READ );
513 else if( xBtm.is() )
515 xRet = implLoadBitmap( xBtm );
518 if( pIStm )
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 );
541 xRet = pUnoGraphic;
545 delete pIStm;
548 return xRet;
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 );
565 else
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 );
593 rGraphic = aBmpEx;
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
668 else
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 );
676 rGraphic = aBmpEx;
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 );
705 break;
707 case( META_PUSH_ACTION ):
709 const MetaPushAction* pA = (const MetaPushAction*)pAction;
710 aDummyVDev.Push( pA->GetFlags() );
711 break;
713 case( META_POP_ACTION ):
715 aDummyVDev.Pop();
716 break;
718 case( META_BMPSCALE_ACTION ):
719 case( META_BMPEXSCALE_ACTION ):
721 BitmapEx aBmpEx;
722 Point aPos;
723 Size aSize;
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();
731 else
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() );
748 else
749 pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() );
751 MetaAction* pDeleteAction = aMtf.ReplaceAction( pNewAction, i );
752 if(pDeleteAction)
753 pDeleteAction->Delete();
754 break;
756 default:
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 ):
763 break;
766 rGraphic = aMtf;
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)
776 SolarMutexGuard g;
778 SvStream* pOStm = NULL;
779 OUString aPath;
780 sal_Int32 i;
782 for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i )
784 const OUString aName( rMediaProperties[ i ].Name );
785 const uno::Any aValue( rMediaProperties[ i ].Value );
787 if (aName == "URL")
789 OUString aURL;
791 aValue >>= aURL;
792 pOStm = ::utl::UcbStreamHelper::CreateStream( aURL, STREAM_WRITE | STREAM_TRUNC );
793 aPath = aURL;
795 else if (aName == "OutputStream")
797 uno::Reference< io::XStream > xOStm;
799 aValue >>= xOStm;
801 if( xOStm.is() )
802 pOStm = ::utl::UcbStreamHelper::CreateStream( xOStm );
806 if( pOStm )
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")
822 OUString aMimeType;
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;
884 else
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() );
895 delete pOStm;
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */