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 .
21 #include <com/sun/star/lang/XUnoTunnel.hpp>
22 #include <sfx2/objsh.hxx>
23 #include <sfx2/docfac.hxx>
24 #include <comphelper/fileformat.h>
25 #include <comphelper/classids.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <unotools/resmgr.hxx>
28 #include <tools/vcompat.hxx>
29 #include <tools/helpers.hxx>
30 #include <vcl/virdev.hxx>
31 #include <svl/itempool.hxx>
32 #include <svx/fmmodel.hxx>
33 #include <svx/fmview.hxx>
34 #include <svx/fmpage.hxx>
35 #include <svx/galmisc.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/dibtools.hxx>
40 #include "gallerydrawmodel.hxx"
42 #include <bitmaps.hlst>
44 using namespace ::com::sun::star
;
46 SgaObject::SgaObject()
52 BitmapEx
SgaObject::createPreviewBitmapEx(const Size
& rSizePixel
) const
56 if(rSizePixel
.Width() && rSizePixel
.Height())
58 if(SgaObjKind::Sound
== GetObjKind())
60 aRetval
= BitmapEx(RID_SVXBMP_GALLERY_MEDIA
);
62 else if(IsThumbBitmap())
64 aRetval
= GetThumbBmp();
68 const Graphic
aGraphic(GetThumbMtf());
70 aRetval
= aGraphic
.GetBitmapEx();
73 if(!aRetval
.IsEmpty())
75 const Size
aCurrentSizePixel(aRetval
.GetSizePixel());
76 const double fScaleX(static_cast<double>(rSizePixel
.Width()) / static_cast<double>(aCurrentSizePixel
.Width()));
77 const double fScaleY(static_cast<double>(rSizePixel
.Height()) / static_cast<double>(aCurrentSizePixel
.Height()));
78 const double fScale(std::min(fScaleX
, fScaleY
));
80 // only scale when need to decrease, no need to make bigger as original. Also
81 // prevent scaling close to 1.0 which is not needed for pixel graphics
82 if(fScale
< 1.0 && fabs(1.0 - fScale
) > 0.005)
84 aRetval
.Scale(fScale
, fScale
, BmpScaleFlag::BestQuality
);
92 bool SgaObject::CreateThumb( const Graphic
& rGraphic
)
96 if( rGraphic
.GetType() == GraphicType::Bitmap
)
98 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
99 Size
aBmpSize( aBmpEx
.GetSizePixel() );
101 if( aBmpSize
.Width() && aBmpSize
.Height() )
103 if( aBmpEx
.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel
&&
104 aBmpEx
.GetPrefSize().Width() > 0 &&
105 aBmpEx
.GetPrefSize().Height() > 0 )
107 Size
aLogSize( OutputDevice::LogicToLogic(aBmpEx
.GetPrefSize(), aBmpEx
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
)) );
109 if( aLogSize
.Width() > 0 && aLogSize
.Height() > 0 )
111 double fFactorLog
= static_cast< double >( aLogSize
.Width() ) / aLogSize
.Height();
112 double fFactorPix
= static_cast< double >( aBmpSize
.Width() ) / aBmpSize
.Height();
114 if( fFactorPix
> fFactorLog
)
115 aBmpSize
.setWidth( FRound( aBmpSize
.Height() * fFactorLog
) );
117 aBmpSize
.setHeight( FRound( aBmpSize
.Width() / fFactorLog
) );
119 aBmpEx
.Scale(aBmpSize
, BmpScaleFlag::BestQuality
);
123 // take over BitmapEx
126 if( ( aBmpSize
.Width() <= S_THUMB
) && ( aBmpSize
.Height() <= S_THUMB
) )
128 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
133 const float fFactor
= static_cast<float>(aBmpSize
.Width()) / aBmpSize
.Height();
134 const Size
aNewSize( std::max( static_cast<long>(fFactor
< 1. ? S_THUMB
* fFactor
: S_THUMB
), 8L ),
135 std::max( static_cast<long>(fFactor
< 1. ? S_THUMB
: S_THUMB
/ fFactor
), 8L ) );
137 static_cast<double>(aNewSize
.Width()) / aBmpSize
.Width(),
138 static_cast<double>(aNewSize
.Height()) / aBmpSize
.Height(),
139 BmpScaleFlag::BestQuality
) )
141 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
147 else if( rGraphic
.GetType() == GraphicType::GdiMetafile
)
149 const Size
aPrefSize( rGraphic
.GetPrefSize() );
150 const double fFactor
= static_cast<double>(aPrefSize
.Width()) / static_cast<double>(aPrefSize
.Height());
151 Size
aSize( S_THUMB
, S_THUMB
);
153 aSize
.setWidth( static_cast<sal_Int32
>( S_THUMB
* fFactor
) );
155 aSize
.setHeight( static_cast<sal_Int32
>( S_THUMB
/ fFactor
) );
157 const GraphicConversionParameters
aParameters(aSize
, false, true, true /*TODO: extra ", true" post-#i121194#*/);
158 aThumbBmp
= rGraphic
.GetBitmapEx(aParameters
);
160 if( !aThumbBmp
.IsEmpty() )
162 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
170 void SgaObject::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
172 static const sal_uInt32 nInventor
= COMPAT_FORMAT( 'S', 'G', 'A', '3' );
174 rOut
.WriteUInt32( nInventor
).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( static_cast<sal_uInt16
>(GetObjKind()) );
175 rOut
.WriteBool( bIsThumbBmp
);
179 const SvStreamCompressFlags nOldCompressMode
= rOut
.GetCompressMode();
180 const sal_uIntPtr nOldVersion
= rOut
.GetVersion();
182 rOut
.SetCompressMode( SvStreamCompressFlags::ZBITMAP
);
183 rOut
.SetVersion( SOFFICE_FILEFORMAT_50
);
185 WriteDIBBitmapEx(aThumbBmp
, rOut
);
187 rOut
.SetVersion( nOldVersion
);
188 rOut
.SetCompressMode( nOldCompressMode
);
191 WriteGDIMetaFile( rOut
, aThumbMtf
);
193 OUString aURLWithoutDestDir
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
194 aURLWithoutDestDir
= aURLWithoutDestDir
.replaceFirst(rDestDir
, "");
195 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aURLWithoutDestDir
, RTL_TEXTENCODING_UTF8
);
198 void SgaObject::ReadData(SvStream
& rIn
, sal_uInt16
& rReadVersion
)
203 rIn
.ReadUInt32( nTmp32
).ReadUInt16( nTmp16
).ReadUInt16( rReadVersion
).ReadUInt16( nTmp16
).ReadCharAsBool( bIsThumbBmp
);
207 ReadDIBBitmapEx(aThumbBmp
, rIn
);
211 ReadGDIMetaFile( rIn
, aThumbMtf
);
214 OUString aTmpStr
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
215 aURL
= INetURLObject(aTmpStr
);
218 OUString
const & SgaObject::GetTitle() const
223 void SgaObject::SetTitle( const OUString
& rTitle
)
228 SvStream
& WriteSgaObject( SvStream
& rOut
, const SgaObject
& rObj
)
230 rObj
.WriteData( rOut
, "" );
234 SvStream
& ReadSgaObject( SvStream
& rIn
, SgaObject
& rObj
)
236 sal_uInt16 nReadVersion
;
238 rObj
.ReadData( rIn
, nReadVersion
);
239 rObj
.bIsValid
= ( rIn
.GetError() == ERRCODE_NONE
);
244 SgaObjectBmp::SgaObjectBmp()
248 SgaObjectBmp::SgaObjectBmp( const INetURLObject
& rURL
)
253 if ( GalleryGraphicImportRet::IMPORT_NONE
!= GalleryGraphicImport( rURL
, aGraphic
, aFilter
) )
254 Init( aGraphic
, rURL
);
257 SgaObjectBmp::SgaObjectBmp( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
259 if( FileExists( rURL
) )
260 Init( rGraphic
, rURL
);
263 void SgaObjectBmp::Init( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
266 bIsValid
= CreateThumb( rGraphic
);
269 void SgaObjectBmp::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
272 SgaObject::WriteData( rOut
, rDestDir
);
273 char const aDummy
[ 10 ] = { 0 };
274 rOut
.WriteBytes(aDummy
, 10);
275 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut
, OString()); //dummy
276 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
279 void SgaObjectBmp::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
282 SgaObject::ReadData( rIn
, rReadVersion
);
283 rIn
.SeekRel( 10 ); // 16, 16, 32, 16
284 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn
); //dummy
286 if( rReadVersion
>= 5 )
287 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
291 SgaObjectSound::SgaObjectSound() :
292 eSoundType( SOUND_STANDARD
)
296 SgaObjectSound::SgaObjectSound( const INetURLObject
& rURL
) :
297 eSoundType( SOUND_STANDARD
)
300 if( FileExists( rURL
) )
303 aThumbBmp
= Bitmap( Size( 1, 1 ), 1 );
310 SgaObjectSound::~SgaObjectSound()
314 BitmapEx
SgaObjectSound::GetThumbBmp() const
320 case SOUND_COMPUTER
: sId
= RID_SVXBMP_GALLERY_SOUND_1
; break;
321 case SOUND_MISC
: sId
= RID_SVXBMP_GALLERY_SOUND_2
; break;
322 case SOUND_MUSIC
: sId
= RID_SVXBMP_GALLERY_SOUND_3
; break;
323 case SOUND_NATURE
: sId
= RID_SVXBMP_GALLERY_SOUND_4
; break;
324 case SOUND_SPEECH
: sId
= RID_SVXBMP_GALLERY_SOUND_5
; break;
325 case SOUND_TECHNIC
: sId
= RID_SVXBMP_GALLERY_SOUND_6
; break;
326 case SOUND_ANIMAL
: sId
= RID_SVXBMP_GALLERY_SOUND_7
; break;
330 sId
= RID_SVXBMP_GALLERY_MEDIA
;
334 const BitmapEx
aBmpEx(sId
);
339 void SgaObjectSound::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
341 SgaObject::WriteData( rOut
, rDestDir
);
342 rOut
.WriteUInt16( eSoundType
);
343 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
346 void SgaObjectSound::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
348 SgaObject::ReadData( rIn
, rReadVersion
);
350 if( rReadVersion
>= 5 )
354 rIn
.ReadUInt16( nTmp16
); eSoundType
= static_cast<GalSoundType
>(nTmp16
);
356 if( rReadVersion
>= 6 )
357 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
361 SgaObjectAnim::SgaObjectAnim()
365 SgaObjectAnim::SgaObjectAnim( const Graphic
& rGraphic
,
366 const INetURLObject
& rURL
)
369 bIsValid
= CreateThumb( rGraphic
);
372 SgaObjectINet::SgaObjectINet()
376 SgaObjectINet::SgaObjectINet( const Graphic
& rGraphic
, const INetURLObject
& rURL
) :
377 SgaObjectAnim ( rGraphic
, rURL
)
381 SgaObjectSvDraw::SgaObjectSvDraw()
385 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel
& rModel
, const INetURLObject
& rURL
)
388 bIsValid
= CreateThumb( rModel
);
392 SvxGalleryDrawModel::SvxGalleryDrawModel()
393 : mpFormModel( nullptr )
396 const OUString
sFactoryURL("sdraw");
398 mxDoc
= SfxObjectShell::CreateObjectByFactoryName( sFactoryURL
);
404 uno::Reference
< lang::XUnoTunnel
> xTunnel( mxDoc
->GetModel(), uno::UNO_QUERY
);
407 mpFormModel
= dynamic_cast< FmFormModel
* >(
408 reinterpret_cast<SdrModel
*>(xTunnel
->getSomething(SdrModel::getUnoTunnelId())));
411 mpFormModel
->InsertPage( mpFormModel
->AllocPage( false ) );
417 SvxGalleryDrawModel::~SvxGalleryDrawModel()
424 SgaObjectSvDraw::SgaObjectSvDraw( SvStream
& rIStm
, const INetURLObject
& rURL
)
426 SvxGalleryDrawModel aModel
;
428 if( aModel
.GetModel() )
430 if( GallerySvDrawImport( rIStm
, *aModel
.GetModel() ) )
433 bIsValid
= CreateThumb( *aModel
.GetModel() );
438 bool SgaObjectSvDraw::CreateThumb( const FmFormModel
& rModel
)
444 if ( CreateIMapGraphic( rModel
, aGraphic
, aImageMap
) )
446 bRet
= SgaObject::CreateThumb( aGraphic
);
450 const FmFormPage
* pPage
= static_cast< const FmFormPage
* >(rModel
.GetPage(0));
454 const tools::Rectangle
aObjRect(pPage
->GetAllObjBoundRect());
456 if(aObjRect
.GetWidth() && aObjRect
.GetHeight())
458 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
459 FmFormView
aView(const_cast< FmFormModel
& >(rModel
), pVDev
);
461 aView
.ShowSdrPage(const_cast< FmFormPage
* >(pPage
));
463 aThumbBmp
= aView
.GetMarkedObjBitmapEx();
465 const Size
aDiscreteSize(aThumbBmp
.GetSizePixel());
467 if(aDiscreteSize
.Width() && aDiscreteSize
.Height())
469 sal_uInt32
nTargetSizeX(S_THUMB
);
470 sal_uInt32
nTargetSizeY(S_THUMB
);
472 if(aDiscreteSize
.Width() > aDiscreteSize
.Height())
474 nTargetSizeY
= (aDiscreteSize
.Height() * nTargetSizeX
) / aDiscreteSize
.Width();
478 nTargetSizeX
= (aDiscreteSize
.Width() * nTargetSizeY
) / aDiscreteSize
.Height();
483 aThumbBmp
.Scale(Size(nTargetSizeX
, nTargetSizeY
), BmpScaleFlag::BestQuality
);
484 aThumbBmp
.Convert(BmpConversion::N8BitColors
);
495 void SgaObjectSvDraw::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
497 SgaObject::WriteData( rOut
, rDestDir
);
498 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
501 void SgaObjectSvDraw::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
503 SgaObject::ReadData( rIn
, rReadVersion
);
505 if( rReadVersion
>= 5 )
506 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */