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 <vcl/svapp.hxx>
21 #include <vcl/image.hxx>
22 #include <vcl/metaact.hxx>
23 #include <vcl/imagerepository.hxx>
24 #include <tools/fract.hxx>
25 #include <unotools/ucbstreamhelper.hxx>
26 #include <vcl/graphicfilter.hxx>
27 #include <vcl/stdtext.hxx>
28 #include <vcl/wmfexternal.hxx>
29 #include <vcl/virdev.hxx>
30 #include <com/sun/star/awt/XBitmap.hpp>
31 #include <com/sun/star/graphic/XGraphicProvider2.hpp>
32 #include <com/sun/star/io/XStream.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/text/GraphicCrop.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include <comphelper/fileformat.h>
37 #include <comphelper/servicehelper.hxx>
38 #include <cppuhelper/implbase.hxx>
39 #include <cppuhelper/supportsservice.hxx>
40 #include <sal/log.hxx>
42 #include <graphic/UnoGraphicDescriptor.hxx>
43 #include <graphic/UnoGraphic.hxx>
44 #include <rtl/ref.hxx>
45 #include <vcl/dibtools.hxx>
46 #include <comphelper/sequence.hxx>
49 using namespace com::sun::star
;
53 class GraphicProvider
: public ::cppu::WeakImplHelper
< css::graphic::XGraphicProvider2
,
54 css::lang::XServiceInfo
>
63 virtual OUString SAL_CALL
getImplementationName() override
;
64 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
65 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
68 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
69 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
72 virtual css::uno::Reference
< css::beans::XPropertySet
> SAL_CALL
queryGraphicDescriptor( const css::uno::Sequence
< css::beans::PropertyValue
>& MediaProperties
) override
;
73 virtual css::uno::Reference
< css::graphic::XGraphic
> SAL_CALL
queryGraphic( const css::uno::Sequence
< css::beans::PropertyValue
>& MediaProperties
) override
;
74 virtual void SAL_CALL
storeGraphic( const css::uno::Reference
< css::graphic::XGraphic
>& Graphic
, const css::uno::Sequence
< css::beans::PropertyValue
>& MediaProperties
) override
;
77 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > SAL_CALL
queryGraphics(const uno::Sequence
< uno::Sequence
<beans::PropertyValue
> >& MediaPropertiesSeq
) override
;
81 static css::uno::Reference
< css::graphic::XGraphic
> implLoadMemory( const OUString
& rResourceURL
);
82 static css::uno::Reference
< css::graphic::XGraphic
> implLoadRepositoryImage( const OUString
& rResourceURL
);
83 static css::uno::Reference
< css::graphic::XGraphic
> implLoadBitmap( const css::uno::Reference
< css::awt::XBitmap
>& rBitmap
);
84 static css::uno::Reference
< css::graphic::XGraphic
> implLoadStandardImage( const OUString
& rResourceURL
);
87 GraphicProvider::GraphicProvider()
91 OUString SAL_CALL
GraphicProvider::getImplementationName()
93 return "com.sun.star.comp.graphic.GraphicProvider";
96 sal_Bool SAL_CALL
GraphicProvider::supportsService( const OUString
& ServiceName
)
98 return cppu::supportsService( this, ServiceName
);
101 uno::Sequence
< OUString
> SAL_CALL
GraphicProvider::getSupportedServiceNames()
103 uno::Sequence
<OUString
> aSeq
{ "com.sun.star.graphic.GraphicProvider" };
107 uno::Sequence
< uno::Type
> SAL_CALL
GraphicProvider::getTypes()
109 static const uno::Sequence
< uno::Type
> aTypes
{
110 cppu::UnoType
<lang::XServiceInfo
>::get(),
111 cppu::UnoType
<lang::XTypeProvider
>::get(),
112 cppu::UnoType
<graphic::XGraphicProvider
>::get()
117 uno::Sequence
< sal_Int8
> SAL_CALL
GraphicProvider::getImplementationId()
119 return css::uno::Sequence
<sal_Int8
>();
122 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadMemory( const OUString
& rResourceURL
)
124 uno::Reference
< ::graphic::XGraphic
> xRet
;
125 sal_Int32 nIndex
= 0;
127 if( rResourceURL
.getToken( 0, '/', nIndex
) == "private:memorygraphic" )
129 sal_Int64 nGraphicAddress
= rResourceURL
.getToken( 0, '/', nIndex
).toInt64();
131 if( nGraphicAddress
)
133 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
135 pUnoGraphic
->init( *reinterpret_cast< ::Graphic
* >( nGraphicAddress
) );
144 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadRepositoryImage( const OUString
& rResourceURL
)
146 uno::Reference
< ::graphic::XGraphic
> xRet
;
149 if( rResourceURL
.startsWith("private:graphicrepository/", &sPathName
) )
152 if ( vcl::ImageRepository::loadImage( sPathName
, aBitmap
) )
154 xRet
= Graphic(aBitmap
).GetXGraphic();
161 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadStandardImage( const OUString
& rResourceURL
)
163 uno::Reference
< ::graphic::XGraphic
> xRet
;
166 if( rResourceURL
.startsWith("private:standardimage/", &sImageName
) )
168 if ( sImageName
== "info" )
170 xRet
= Graphic(GetStandardInfoBoxImage().GetBitmapEx()).GetXGraphic();
172 else if ( sImageName
== "warning" )
174 xRet
= Graphic(GetStandardWarningBoxImage().GetBitmapEx()).GetXGraphic();
176 else if ( sImageName
== "error" )
178 xRet
= Graphic(GetStandardErrorBoxImage().GetBitmapEx()).GetXGraphic();
180 else if ( sImageName
== "query" )
182 xRet
= Graphic(GetStandardQueryBoxImage().GetBitmapEx()).GetXGraphic();
189 uno::Reference
< ::graphic::XGraphic
> GraphicProvider::implLoadBitmap( const uno::Reference
< awt::XBitmap
>& xBtm
)
191 uno::Reference
< ::graphic::XGraphic
> xRet
;
192 uno::Sequence
< sal_Int8
> aBmpSeq( xBtm
->getDIB() );
193 uno::Sequence
< sal_Int8
> aMaskSeq( xBtm
->getMaskDIB() );
194 SvMemoryStream
aBmpStream( aBmpSeq
.getArray(), aBmpSeq
.getLength(), StreamMode::READ
);
198 ReadDIB(aBmp
, aBmpStream
, true);
200 if( aMaskSeq
.hasElements() )
202 SvMemoryStream
aMaskStream( aMaskSeq
.getArray(), aMaskSeq
.getLength(), StreamMode::READ
);
205 ReadDIB(aMask
, aMaskStream
, true);
206 aBmpEx
= BitmapEx( aBmp
, aMask
);
209 aBmpEx
= BitmapEx( aBmp
);
211 if( !aBmpEx
.IsEmpty() )
213 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
215 pUnoGraphic
->init( aBmpEx
);
221 uno::Reference
< beans::XPropertySet
> SAL_CALL
GraphicProvider::queryGraphicDescriptor( const uno::Sequence
< beans::PropertyValue
>& rMediaProperties
)
223 uno::Reference
< beans::XPropertySet
> xRet
;
226 uno::Reference
< io::XInputStream
> xIStm
;
227 uno::Reference
< awt::XBitmap
>xBtm
;
229 for( const auto& rMediaProperty
: rMediaProperties
)
234 const OUString
aName( rMediaProperty
.Name
);
235 const uno::Any
aValue( rMediaProperty
.Value
);
241 else if (aName
== "InputStream")
245 else if (aName
== "Bitmap")
255 unographic::GraphicDescriptor
* pDescriptor
= new unographic::GraphicDescriptor
;
256 pDescriptor
->init( xIStm
, aURL
);
259 else if( !aURL
.isEmpty() )
261 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadMemory( aURL
) );
263 if ( !xGraphic
.is() )
264 xGraphic
= implLoadRepositoryImage( aURL
);
266 if ( !xGraphic
.is() )
267 xGraphic
= implLoadStandardImage( aURL
);
271 xRet
.set( xGraphic
, uno::UNO_QUERY
);
275 unographic::GraphicDescriptor
* pDescriptor
= new unographic::GraphicDescriptor
;
276 pDescriptor
->init( aURL
);
282 uno::Reference
< ::graphic::XGraphic
> xGraphic( implLoadBitmap( xBtm
) );
284 xRet
.set( xGraphic
, uno::UNO_QUERY
);
291 uno::Reference
< ::graphic::XGraphic
> SAL_CALL
GraphicProvider::queryGraphic( const uno::Sequence
< ::beans::PropertyValue
>& rMediaProperties
)
293 uno::Reference
< ::graphic::XGraphic
> xRet
;
296 uno::Reference
< io::XInputStream
> xIStm
;
297 uno::Reference
< awt::XBitmap
>xBtm
;
299 uno::Sequence
< ::beans::PropertyValue
> aFilterData
;
301 bool bLazyRead
= false;
302 bool bLoadAsLink
= false;
304 for (const auto& rMediaProperty
: rMediaProperties
)
309 const OUString
aName( rMediaProperty
.Name
);
310 const uno::Any
aValue( rMediaProperty
.Value
);
318 else if (aName
== "InputStream")
322 else if (aName
== "Bitmap")
326 else if (aName
== "FilterData")
328 aValue
>>= aFilterData
;
330 else if (aName
== "LazyRead")
332 aValue
>>= bLazyRead
;
334 else if (aName
== "LoadAsLink")
336 aValue
>>= bLoadAsLink
;
340 // Check for the goal width and height if they are defined
341 sal_uInt16 nExtWidth
= 0;
342 sal_uInt16 nExtHeight
= 0;
343 sal_uInt16 nExtMapMode
= 0;
344 for( const auto& rProp
: std::as_const(aFilterData
) )
346 const OUString
aName( rProp
.Name
);
347 const uno::Any
aValue( rProp
.Value
);
349 if (aName
== "ExternalWidth")
351 aValue
>>= nExtWidth
;
353 else if (aName
== "ExternalHeight")
355 aValue
>>= nExtHeight
;
357 else if (aName
== "ExternalMapMode")
359 aValue
>>= nExtMapMode
;
365 std::unique_ptr
<SvStream
> pIStm
;
369 pIStm
= ::utl::UcbStreamHelper::CreateStream( xIStm
);
371 else if( !aPath
.isEmpty() )
373 xRet
= implLoadMemory( aPath
);
376 xRet
= implLoadRepositoryImage( aPath
);
379 xRet
= implLoadStandardImage( aPath
);
382 pIStm
= ::utl::UcbStreamHelper::CreateStream( aPath
, StreamMode::READ
);
386 xRet
= implLoadBitmap( xBtm
);
391 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
396 // Define APM Header if goal height and width are defined
397 WmfExternal aExtHeader
;
398 aExtHeader
.xExt
= nExtWidth
;
399 aExtHeader
.yExt
= nExtHeight
;
400 aExtHeader
.mapMode
= nExtMapMode
;
401 WmfExternal
*pExtHeader
= nullptr;
402 if ( nExtMapMode
> 0 )
404 pExtHeader
= &aExtHeader
;
408 ErrCode error
= ERRCODE_NONE
;
411 Graphic aGraphic
= rFilter
.ImportUnloadedGraphic(*pIStm
);
412 if (!aGraphic
.IsNone())
413 aVCLGraphic
= aGraphic
;
415 if (aVCLGraphic
.IsNone())
416 error
= rFilter
.ImportGraphic(aVCLGraphic
, aPath
, *pIStm
, GRFILTER_FORMAT_DONTKNOW
,
417 nullptr, GraphicFilterImportFlags::NONE
, pExtHeader
);
419 if( (error
== ERRCODE_NONE
) &&
420 ( aVCLGraphic
.GetType() != GraphicType::NONE
) )
422 if (!aPath
.isEmpty() && bLoadAsLink
)
423 aVCLGraphic
.setOriginURL(aPath
);
425 ::unographic::Graphic
* pUnoGraphic
= new ::unographic::Graphic
;
427 pUnoGraphic
->init( aVCLGraphic
);
431 SAL_WARN("svtools", "Could not create graphic: " << error
);
439 uno::Sequence
< uno::Reference
<graphic::XGraphic
> > SAL_CALL
GraphicProvider::queryGraphics(const uno::Sequence
< uno::Sequence
<beans::PropertyValue
> >& rMediaPropertiesSeq
)
441 SolarMutexGuard aGuard
;
443 // Turn properties into streams.
444 std::vector
< std::unique_ptr
<SvStream
> > aStreams
;
445 for (const auto& rMediaProperties
: rMediaPropertiesSeq
)
447 std::unique_ptr
<SvStream
> pStream
;
448 uno::Reference
<io::XInputStream
> xStream
;
450 auto pProp
= std::find_if(rMediaProperties
.begin(), rMediaProperties
.end(),
451 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
== "InputStream"; });
452 if (pProp
!= rMediaProperties
.end())
454 pProp
->Value
>>= xStream
;
456 pStream
= utl::UcbStreamHelper::CreateStream(xStream
);
459 aStreams
.push_back(std::move(pStream
));
462 // Import: streams to graphics.
463 std::vector
< std::shared_ptr
<Graphic
> > aGraphics
;
464 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
465 rFilter
.ImportGraphics(aGraphics
, std::move(aStreams
));
467 // Returning: graphics to UNO objects.
468 std::vector
< uno::Reference
<graphic::XGraphic
> > aRet
;
469 for (const auto& pGraphic
: aGraphics
)
471 uno::Reference
<graphic::XGraphic
> xGraphic
;
475 auto pUnoGraphic
= new unographic::Graphic();
476 pUnoGraphic
->init(*pGraphic
);
477 xGraphic
= pUnoGraphic
;
480 aRet
.push_back(xGraphic
);
483 return comphelper::containerToSequence(aRet
);
486 void ImplCalculateCropRect( ::Graphic
const & rGraphic
, const text::GraphicCrop
& rGraphicCropLogic
, tools::Rectangle
& rGraphicCropPixel
)
488 if ( !(rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
) )
491 Size
aSourceSizePixel( rGraphic
.GetSizePixel() );
492 if ( !(aSourceSizePixel
.Width() && aSourceSizePixel
.Height()) )
495 if ( !(rGraphicCropLogic
.Left
|| rGraphicCropLogic
.Top
|| rGraphicCropLogic
.Right
|| rGraphicCropLogic
.Bottom
) )
498 Size
aSize100thMM( 0, 0 );
499 if( rGraphic
.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel
)
501 aSize100thMM
= OutputDevice::LogicToLogic(rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
));
505 aSize100thMM
= Application::GetDefaultDevice()->PixelToLogic(rGraphic
.GetPrefSize(), MapMode(MapUnit::Map100thMM
));
507 if ( aSize100thMM
.Width() && aSize100thMM
.Height() )
509 double fSourceSizePixelWidth
= static_cast<double>(aSourceSizePixel
.Width());
510 double fSourceSizePixelHeight
= static_cast<double>(aSourceSizePixel
.Height());
511 rGraphicCropPixel
.SetLeft( static_cast< sal_Int32
>((fSourceSizePixelWidth
* rGraphicCropLogic
.Left
) / aSize100thMM
.Width()) );
512 rGraphicCropPixel
.SetTop( static_cast< sal_Int32
>((fSourceSizePixelHeight
* rGraphicCropLogic
.Top
) / aSize100thMM
.Height()) );
513 rGraphicCropPixel
.SetRight( static_cast< sal_Int32
>(( fSourceSizePixelWidth
* ( aSize100thMM
.Width() - rGraphicCropLogic
.Right
) ) / aSize100thMM
.Width() ) );
514 rGraphicCropPixel
.SetBottom( static_cast< sal_Int32
>(( fSourceSizePixelHeight
* ( aSize100thMM
.Height() - rGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height() ) );
518 void ImplApplyBitmapScaling( ::Graphic
& rGraphic
, sal_Int32 nPixelWidth
, sal_Int32 nPixelHeight
)
520 if ( nPixelWidth
&& nPixelHeight
)
522 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
523 MapMode
aPrefMapMode( aBmpEx
.GetPrefMapMode() );
524 Size
aPrefSize( aBmpEx
.GetPrefSize() );
525 aBmpEx
.Scale( Size( nPixelWidth
, nPixelHeight
) );
526 aBmpEx
.SetPrefMapMode( aPrefMapMode
);
527 aBmpEx
.SetPrefSize( aPrefSize
);
532 void ImplApplyBitmapResolution( ::Graphic
& rGraphic
, sal_Int32 nImageResolution
, const Size
& rVisiblePixelSize
, const awt::Size
& rLogicalSize
)
534 if ( !(nImageResolution
&& rLogicalSize
.Width
&& rLogicalSize
.Height
) )
537 const double fImageResolution
= static_cast<double>( nImageResolution
);
538 const double fSourceDPIX
= ( static_cast<double>(rVisiblePixelSize
.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Width
);
539 const double fSourceDPIY
= ( static_cast<double>(rVisiblePixelSize
.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize
.Height
);
540 const sal_Int32
nSourcePixelWidth( rGraphic
.GetSizePixel().Width() );
541 const sal_Int32
nSourcePixelHeight( rGraphic
.GetSizePixel().Height() );
542 const double fSourcePixelWidth
= static_cast<double>( nSourcePixelWidth
);
543 const double fSourcePixelHeight
= static_cast<double>( nSourcePixelHeight
);
545 sal_Int32 nDestPixelWidth
= nSourcePixelWidth
;
546 sal_Int32 nDestPixelHeight
= nSourcePixelHeight
;
548 // check, if the bitmap DPI exceeds the maximum DPI
549 if( fSourceDPIX
> fImageResolution
)
551 nDestPixelWidth
= static_cast<sal_Int32
>(( fSourcePixelWidth
* fImageResolution
) / fSourceDPIX
);
552 if ( !nDestPixelWidth
|| ( nDestPixelWidth
> nSourcePixelWidth
) )
553 nDestPixelWidth
= nSourcePixelWidth
;
555 if ( fSourceDPIY
> fImageResolution
)
557 nDestPixelHeight
= static_cast<sal_Int32
>(( fSourcePixelHeight
* fImageResolution
) / fSourceDPIY
);
558 if ( !nDestPixelHeight
|| ( nDestPixelHeight
> nSourcePixelHeight
) )
559 nDestPixelHeight
= nSourcePixelHeight
;
561 if ( ( nDestPixelWidth
!= nSourcePixelWidth
) || ( nDestPixelHeight
!= nSourcePixelHeight
) )
562 ImplApplyBitmapScaling( rGraphic
, nDestPixelWidth
, nDestPixelHeight
);
565 void ImplApplyFilterData( ::Graphic
& rGraphic
, const uno::Sequence
< beans::PropertyValue
>& rFilterData
)
567 /* this method applies following attributes to the graphic, in the first step the
568 cropping area (logical size in 100thmm) is applied, in the second step the resolution
569 is applied, in the third step the graphic is scaled to the corresponding pixelsize.
570 if a parameter value is zero or not available the corresponding step will be skipped */
572 sal_Int32 nPixelWidth
= 0;
573 sal_Int32 nPixelHeight
= 0;
574 sal_Int32 nImageResolution
= 0;
575 awt::Size
aLogicalSize( 0, 0 );
576 text::GraphicCrop
aCropLogic( 0, 0, 0, 0 );
577 bool bRemoveCropArea
= true;
579 for( const auto& rProp
: rFilterData
)
581 const OUString
aName( rProp
.Name
);
582 const uno::Any
aValue( rProp
.Value
);
584 if (aName
== "PixelWidth")
585 aValue
>>= nPixelWidth
;
586 else if (aName
== "PixelHeight")
587 aValue
>>= nPixelHeight
;
588 else if (aName
== "LogicalSize")
589 aValue
>>= aLogicalSize
;
590 else if (aName
== "GraphicCropLogic")
591 aValue
>>= aCropLogic
;
592 else if (aName
== "RemoveCropArea")
593 aValue
>>= bRemoveCropArea
;
594 else if (aName
== "ImageResolution")
595 aValue
>>= nImageResolution
;
597 if ( rGraphic
.GetType() == GraphicType::Bitmap
)
599 if(rGraphic
.getVectorGraphicData().get())
601 // embedded Vector Graphic Data, no need to scale. Also no method to apply crop data currently
605 tools::Rectangle
aCropPixel( Point( 0, 0 ), rGraphic
.GetSizePixel() );
606 ImplCalculateCropRect( rGraphic
, aCropLogic
, aCropPixel
);
607 if ( bRemoveCropArea
)
609 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
610 aBmpEx
.Crop( aCropPixel
);
613 Size
aVisiblePixelSize( bRemoveCropArea
? rGraphic
.GetSizePixel() : aCropPixel
.GetSize() );
614 ImplApplyBitmapResolution( rGraphic
, nImageResolution
, aVisiblePixelSize
, aLogicalSize
);
615 ImplApplyBitmapScaling( rGraphic
, nPixelWidth
, nPixelHeight
);
618 else if ( ( rGraphic
.GetType() == GraphicType::GdiMetafile
) && nImageResolution
)
620 ScopedVclPtrInstance
< VirtualDevice
> aDummyVDev
;
621 GDIMetaFile
aMtf( rGraphic
.GetGDIMetaFile() );
622 Size
aMtfSize( OutputDevice::LogicToLogic(aMtf
.GetPrefSize(), aMtf
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
)) );
623 if ( aMtfSize
.Width() && aMtfSize
.Height() )
625 MapMode
aNewMapMode( MapUnit::Map100thMM
);
626 aNewMapMode
.SetScaleX( Fraction( aLogicalSize
.Width
, aMtfSize
.Width() ) );
627 aNewMapMode
.SetScaleY( Fraction( aLogicalSize
.Height
, aMtfSize
.Height() ) );
628 aDummyVDev
->EnableOutput( false );
629 aDummyVDev
->SetMapMode( aNewMapMode
);
631 for( size_t i
= 0, nObjCount
= aMtf
.GetActionSize(); i
< nObjCount
; i
++ )
633 MetaAction
* pAction
= aMtf
.GetAction( i
);
634 switch( pAction
->GetType() )
636 // only optimizing common bitmap actions:
637 case MetaActionType::MAPMODE
:
639 pAction
->Execute( aDummyVDev
.get() );
642 case MetaActionType::PUSH
:
644 const MetaPushAction
* pA
= static_cast<const MetaPushAction
*>(pAction
);
645 aDummyVDev
->Push( pA
->GetFlags() );
648 case MetaActionType::POP
:
653 case MetaActionType::BMPSCALE
:
654 case MetaActionType::BMPEXSCALE
:
659 if ( pAction
->GetType() == MetaActionType::BMPSCALE
)
661 MetaBmpScaleAction
* pScaleAction
= dynamic_cast< MetaBmpScaleAction
* >( pAction
);
662 assert(pScaleAction
);
663 aBmpEx
= pScaleAction
->GetBitmap();
664 aPos
= pScaleAction
->GetPoint();
665 aSize
= pScaleAction
->GetSize();
669 MetaBmpExScaleAction
* pScaleAction
= dynamic_cast< MetaBmpExScaleAction
* >( pAction
);
670 assert(pScaleAction
);
671 aBmpEx
= pScaleAction
->GetBitmapEx();
672 aPos
= pScaleAction
->GetPoint();
673 aSize
= pScaleAction
->GetSize();
675 ::Graphic
aGraphic( aBmpEx
);
676 const Size
aSize100thmm( aDummyVDev
->LogicToPixel( aSize
) );
677 Size
aSize100thmm2( aDummyVDev
->PixelToLogic(aSize100thmm
, MapMode(MapUnit::Map100thMM
)) );
679 ImplApplyBitmapResolution( aGraphic
, nImageResolution
,
680 aGraphic
.GetSizePixel(), awt::Size( aSize100thmm2
.Width(), aSize100thmm2
.Height() ) );
682 rtl::Reference
<MetaAction
> pNewAction
= new MetaBmpExScaleAction( aPos
, aSize
, aGraphic
.GetBitmapEx() );
683 aMtf
.ReplaceAction( pNewAction
, i
);
687 case MetaActionType::BMP
:
688 case MetaActionType::BMPSCALEPART
:
689 case MetaActionType::BMPEX
:
690 case MetaActionType::BMPEXSCALEPART
:
691 case MetaActionType::MASK
:
692 case MetaActionType::MASKSCALE
:
702 void SAL_CALL
GraphicProvider::storeGraphic( const uno::Reference
< ::graphic::XGraphic
>& rxGraphic
, const uno::Sequence
< beans::PropertyValue
>& rMediaProperties
)
706 std::unique_ptr
<SvStream
> pOStm
;
709 for( const auto& rMediaProperty
: rMediaProperties
)
711 const OUString
aName( rMediaProperty
.Name
);
712 const uno::Any
aValue( rMediaProperty
.Value
);
719 pOStm
= ::utl::UcbStreamHelper::CreateStream( aURL
, StreamMode::WRITE
| StreamMode::TRUNC
);
722 else if (aName
== "OutputStream")
724 uno::Reference
< io::XStream
> xOStm
;
729 pOStm
= ::utl::UcbStreamHelper::CreateStream( xOStm
);
739 uno::Sequence
< beans::PropertyValue
> aFilterDataSeq
;
740 const char* pFilterShortName
= nullptr;
742 for( const auto& rMediaProperty
: rMediaProperties
)
744 const OUString
aName( rMediaProperty
.Name
);
745 const uno::Any
aValue( rMediaProperty
.Value
);
747 if (aName
== "FilterData")
749 aValue
>>= aFilterDataSeq
;
751 else if (aName
== "MimeType")
755 aValue
>>= aMimeType
;
757 if (aMimeType
== MIMETYPE_BMP
)
758 pFilterShortName
= "bmp";
759 else if (aMimeType
== MIMETYPE_EPS
)
760 pFilterShortName
= "eps";
761 else if (aMimeType
== MIMETYPE_GIF
)
762 pFilterShortName
= "gif";
763 else if (aMimeType
== MIMETYPE_JPG
)
764 pFilterShortName
= "jpg";
765 else if (aMimeType
== MIMETYPE_MET
)
766 pFilterShortName
= "met";
767 else if (aMimeType
== MIMETYPE_PNG
)
768 pFilterShortName
= "png";
769 else if (aMimeType
== MIMETYPE_PCT
)
770 pFilterShortName
= "pct";
771 else if (aMimeType
== MIMETYPE_PBM
)
772 pFilterShortName
= "pbm";
773 else if (aMimeType
== MIMETYPE_PGM
)
774 pFilterShortName
= "pgm";
775 else if (aMimeType
== MIMETYPE_PPM
)
776 pFilterShortName
= "ppm";
777 else if (aMimeType
== MIMETYPE_RAS
)
778 pFilterShortName
= "ras";
779 else if (aMimeType
== MIMETYPE_SVM
)
780 pFilterShortName
= "svm";
781 else if (aMimeType
== MIMETYPE_TIF
)
782 pFilterShortName
= "tif";
783 else if (aMimeType
== MIMETYPE_EMF
)
784 pFilterShortName
= "emf";
785 else if (aMimeType
== MIMETYPE_WMF
)
786 pFilterShortName
= "wmf";
787 else if (aMimeType
== MIMETYPE_XPM
)
788 pFilterShortName
= "xpm";
789 else if (aMimeType
== MIMETYPE_SVG
)
790 pFilterShortName
= "svg";
791 else if (aMimeType
== MIMETYPE_VCLGRAPHIC
)
792 pFilterShortName
= MIMETYPE_VCLGRAPHIC
;
796 if( !pFilterShortName
)
799 ::GraphicFilter
& rFilter
= ::GraphicFilter::GetGraphicFilter();
802 const uno::Reference
< XInterface
> xIFace( rxGraphic
, uno::UNO_QUERY
);
803 const ::Graphic
* pGraphic
= comphelper::getUnoTunnelImplementation
<::Graphic
>( xIFace
);
805 if( pGraphic
&& ( pGraphic
->GetType() != GraphicType::NONE
) )
807 ::Graphic
aGraphic( *pGraphic
);
808 ImplApplyFilterData( aGraphic
, aFilterDataSeq
);
810 /* sj: using a temporary memory stream, because some graphic filters are seeking behind
811 stream end (which leads to an invalid argument exception then). */
812 SvMemoryStream aMemStrm
;
813 aMemStrm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
814 if( 0 == strcmp( pFilterShortName
, MIMETYPE_VCLGRAPHIC
) )
815 WriteGraphic( aMemStrm
, aGraphic
);
818 rFilter
.ExportGraphic( aGraphic
, aPath
, aMemStrm
,
819 rFilter
.GetExportFormatNumberForShortName( OUString::createFromAscii( pFilterShortName
) ),
820 ( aFilterDataSeq
.hasElements() ? &aFilterDataSeq
: nullptr ) );
822 pOStm
->WriteBytes( aMemStrm
.GetData(), aMemStrm
.TellEnd() );
829 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
830 com_sun_star_comp_graphic_GraphicProvider_get_implementation(
831 css::uno::XComponentContext
*,
832 css::uno::Sequence
<css::uno::Any
> const &)
834 return cppu::acquire(new GraphicProvider
);
837 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */