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 <sal/config.h>
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <sfx2/objsh.hxx>
24 #include <comphelper/fileformat.h>
25 #include <comphelper/servicehelper.hxx>
26 #include <tools/vcompat.hxx>
27 #include <tools/helpers.hxx>
28 #include <vcl/virdev.hxx>
29 #include <svx/fmmodel.hxx>
30 #include <svx/fmview.hxx>
31 #include <svx/fmpage.hxx>
32 #include <svx/galmisc.hxx>
34 #include <vcl/dibtools.hxx>
35 #include <vcl/filter/SvmReader.hxx>
36 #include <vcl/filter/SvmWriter.hxx>
37 #include "gallerydrawmodel.hxx"
38 #include <bitmaps.hlst>
40 using namespace ::com::sun::star
;
42 SgaObject::SgaObject()
48 SgaObject::SgaObject(const SgaObject
& aObject
)
49 : aThumbBmp(aObject
.aThumbBmp
)
50 , aThumbMtf(aObject
.aThumbMtf
)
52 , aTitle(aObject
.aTitle
)
53 , bIsValid(aObject
.bIsValid
)
54 , bIsThumbBmp(aObject
.bIsThumbBmp
)
58 BitmapEx
SgaObject::createPreviewBitmapEx(const Size
& rSizePixel
) const
62 if(rSizePixel
.Width() && rSizePixel
.Height())
64 if(SgaObjKind::Sound
== GetObjKind())
66 aRetval
= BitmapEx(RID_SVXBMP_GALLERY_MEDIA
);
68 else if(IsThumbBitmap())
70 aRetval
= GetThumbBmp();
74 const Graphic
aGraphic(GetThumbMtf());
76 aRetval
= aGraphic
.GetBitmapEx();
79 if(!aRetval
.IsEmpty())
81 const Size
aCurrentSizePixel(aRetval
.GetSizePixel());
82 const double fScaleX(static_cast<double>(rSizePixel
.Width()) / static_cast<double>(aCurrentSizePixel
.Width()));
83 const double fScaleY(static_cast<double>(rSizePixel
.Height()) / static_cast<double>(aCurrentSizePixel
.Height()));
84 const double fScale(std::min(fScaleX
, fScaleY
));
86 // only scale when need to decrease, no need to make bigger as original. Also
87 // prevent scaling close to 1.0 which is not needed for pixel graphics
88 if(fScale
< 1.0 && fabs(1.0 - fScale
) > 0.005)
90 aRetval
.Scale(fScale
, fScale
, BmpScaleFlag::BestQuality
);
98 bool SgaObject::CreateThumb( const Graphic
& rGraphic
)
102 if( rGraphic
.GetType() == GraphicType::Bitmap
)
104 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
105 Size
aBmpSize( aBmpEx
.GetSizePixel() );
107 if( aBmpSize
.Width() && aBmpSize
.Height() )
109 if( aBmpEx
.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel
&&
110 aBmpEx
.GetPrefSize().Width() > 0 &&
111 aBmpEx
.GetPrefSize().Height() > 0 )
113 Size
aLogSize( OutputDevice::LogicToLogic(aBmpEx
.GetPrefSize(), aBmpEx
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
)) );
115 if( !aLogSize
.IsEmpty() )
117 double fFactorLog
= static_cast< double >( aLogSize
.Width() ) / aLogSize
.Height();
118 double fFactorPix
= static_cast< double >( aBmpSize
.Width() ) / aBmpSize
.Height();
120 if( fFactorPix
> fFactorLog
)
121 aBmpSize
.setWidth( basegfx::fround
<tools::Long
>( aBmpSize
.Height() * fFactorLog
) );
123 aBmpSize
.setHeight( basegfx::fround
<tools::Long
>( aBmpSize
.Width() / fFactorLog
) );
125 aBmpEx
.Scale(aBmpSize
, BmpScaleFlag::BestQuality
);
129 // take over BitmapEx
132 if( ( aBmpSize
.Width() <= S_THUMB
) && ( aBmpSize
.Height() <= S_THUMB
) )
134 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
139 const float fFactor
= static_cast<float>(aBmpSize
.Width()) / aBmpSize
.Height();
140 const Size
aNewSize( std::max( tools::Long(fFactor
< 1. ? S_THUMB
* fFactor
: S_THUMB
), tools::Long(8) ),
141 std::max( tools::Long(fFactor
< 1. ? S_THUMB
: S_THUMB
/ fFactor
), tools::Long(8) ) );
143 static_cast<double>(aNewSize
.Width()) / aBmpSize
.Width(),
144 static_cast<double>(aNewSize
.Height()) / aBmpSize
.Height(),
145 BmpScaleFlag::BestQuality
) )
147 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
153 else if( rGraphic
.GetType() == GraphicType::GdiMetafile
)
155 const Size
aPrefSize( rGraphic
.GetPrefSize() );
156 const double fFactor
= static_cast<double>(aPrefSize
.Width()) / static_cast<double>(aPrefSize
.Height());
157 Size
aSize( S_THUMB
, S_THUMB
);
159 aSize
.setWidth( static_cast<sal_Int32
>( S_THUMB
* fFactor
) );
161 aSize
.setHeight( static_cast<sal_Int32
>( S_THUMB
/ fFactor
) );
163 const GraphicConversionParameters
aParameters(aSize
, false, true, true /*TODO: extra ", true" post-#i121194#*/);
164 aThumbBmp
= rGraphic
.GetBitmapEx(aParameters
);
166 if( !aThumbBmp
.IsEmpty() )
168 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
176 void SgaObject::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
178 static const sal_uInt32 nInventor
= COMPAT_FORMAT( 'S', 'G', 'A', '3' );
180 rOut
.WriteUInt32( nInventor
).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( static_cast<sal_uInt16
>(GetObjKind()) );
181 rOut
.WriteBool( bIsThumbBmp
);
185 const SvStreamCompressFlags nOldCompressMode
= rOut
.GetCompressMode();
186 const sal_Int32 nOldVersion
= rOut
.GetVersion();
188 rOut
.SetCompressMode( SvStreamCompressFlags::ZBITMAP
);
189 rOut
.SetVersion( SOFFICE_FILEFORMAT_50
);
191 WriteDIBBitmapEx(aThumbBmp
, rOut
);
193 rOut
.SetVersion( nOldVersion
);
194 rOut
.SetCompressMode( nOldCompressMode
);
200 SvmWriter
aWriter(rOut
);
201 aWriter
.Write(aThumbMtf
);
205 OUString aURLWithoutDestDir
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
206 aURLWithoutDestDir
= aURLWithoutDestDir
.replaceFirst(rDestDir
, "");
207 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aURLWithoutDestDir
, RTL_TEXTENCODING_UTF8
);
210 void SgaObject::ReadData(SvStream
& rIn
, sal_uInt16
& rReadVersion
)
215 rIn
.ReadUInt32( nTmp32
).ReadUInt16( nTmp16
).ReadUInt16( rReadVersion
).ReadUInt16( nTmp16
).ReadCharAsBool( bIsThumbBmp
);
219 ReadDIBBitmapEx(aThumbBmp
, rIn
);
223 SvmReader
aReader( rIn
);
224 aReader
.Read( aThumbMtf
);
227 OUString aTmpStr
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
228 aURL
= INetURLObject(aTmpStr
);
231 OUString
const & SgaObject::GetTitle() const
236 void SgaObject::SetTitle( const OUString
& rTitle
)
241 SvStream
& WriteSgaObject( SvStream
& rOut
, const SgaObject
& rObj
)
243 rObj
.WriteData( rOut
, u
""_ustr
);
247 SvStream
& ReadSgaObject( SvStream
& rIn
, SgaObject
& rObj
)
249 sal_uInt16 nReadVersion
;
251 rObj
.ReadData( rIn
, nReadVersion
);
252 rObj
.bIsValid
= ( rIn
.GetError() == ERRCODE_NONE
);
257 SgaObjectBmp::SgaObjectBmp()
261 SgaObjectBmp::SgaObjectBmp( const INetURLObject
& rURL
)
266 if ( GalleryGraphicImportRet::IMPORT_NONE
!= GalleryGraphicImport( rURL
, aGraphic
, aFilter
) )
267 Init( aGraphic
, rURL
);
270 SgaObjectBmp::SgaObjectBmp( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
272 if( FileExists( rURL
) )
273 Init( rGraphic
, rURL
);
276 void SgaObjectBmp::Init( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
279 bIsValid
= CreateThumb( rGraphic
);
282 void SgaObjectBmp::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
285 SgaObject::WriteData( rOut
, rDestDir
);
286 char const aDummy
[ 10 ] = { 0 };
287 rOut
.WriteBytes(aDummy
, 10);
288 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut
, ""); //dummy
289 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
292 void SgaObjectBmp::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
295 SgaObject::ReadData( rIn
, rReadVersion
);
296 rIn
.SeekRel( 10 ); // 16, 16, 32, 16
297 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn
); //dummy
299 if( rReadVersion
>= 5 )
300 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
304 SgaObjectSound::SgaObjectSound() :
305 eSoundType( SOUND_STANDARD
)
309 SgaObjectSound::SgaObjectSound( const INetURLObject
& rURL
) :
310 eSoundType( SOUND_STANDARD
)
313 if( FileExists( rURL
) )
316 aThumbBmp
= Bitmap(Size(1, 1), vcl::PixelFormat::N8_BPP
);
323 SgaObjectSound::~SgaObjectSound()
327 BitmapEx
SgaObjectSound::GetThumbBmp() const
333 case SOUND_COMPUTER
: sId
= RID_SVXBMP_GALLERY_SOUND_1
; break;
334 case SOUND_MISC
: sId
= RID_SVXBMP_GALLERY_SOUND_2
; break;
335 case SOUND_MUSIC
: sId
= RID_SVXBMP_GALLERY_SOUND_3
; break;
336 case SOUND_NATURE
: sId
= RID_SVXBMP_GALLERY_SOUND_4
; break;
337 case SOUND_SPEECH
: sId
= RID_SVXBMP_GALLERY_SOUND_5
; break;
338 case SOUND_TECHNIC
: sId
= RID_SVXBMP_GALLERY_SOUND_6
; break;
339 case SOUND_ANIMAL
: sId
= RID_SVXBMP_GALLERY_SOUND_7
; break;
343 sId
= RID_SVXBMP_GALLERY_MEDIA
;
347 const BitmapEx
aBmpEx(sId
);
352 void SgaObjectSound::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
354 SgaObject::WriteData( rOut
, rDestDir
);
355 rOut
.WriteUInt16( eSoundType
);
356 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
359 void SgaObjectSound::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
361 SgaObject::ReadData( rIn
, rReadVersion
);
363 if( rReadVersion
>= 5 )
367 rIn
.ReadUInt16( nTmp16
); eSoundType
= static_cast<GalSoundType
>(nTmp16
);
369 if( rReadVersion
>= 6 )
370 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
374 SgaObjectAnim::SgaObjectAnim()
378 SgaObjectAnim::SgaObjectAnim( const Graphic
& rGraphic
,
379 const INetURLObject
& rURL
)
382 bIsValid
= CreateThumb( rGraphic
);
385 SgaObjectINet::SgaObjectINet()
389 SgaObjectINet::SgaObjectINet( const Graphic
& rGraphic
, const INetURLObject
& rURL
) :
390 SgaObjectAnim ( rGraphic
, rURL
)
394 SgaObjectSvDraw::SgaObjectSvDraw()
398 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel
& rModel
, const INetURLObject
& rURL
)
401 bIsValid
= CreateThumb( rModel
);
405 SvxGalleryDrawModel::SvxGalleryDrawModel()
406 : mpFormModel( nullptr )
408 mxDoc
= SfxObjectShell::CreateObjectByFactoryName( u
"sdraw"_ustr
);
416 = dynamic_cast<FmFormModel
*>(comphelper::getFromUnoTunnel
<SdrModel
>(mxDoc
->GetModel()));
419 mpFormModel
->InsertPage(mpFormModel
->AllocPage(false).get());
423 SvxGalleryDrawModel::~SvxGalleryDrawModel()
430 SgaObjectSvDraw::SgaObjectSvDraw( SvStream
& rIStm
, const INetURLObject
& rURL
)
432 SvxGalleryDrawModel aModel
;
434 if( aModel
.GetModel() )
436 if( GallerySvDrawImport( rIStm
, *aModel
.GetModel() ) )
439 bIsValid
= CreateThumb( *aModel
.GetModel() );
444 bool SgaObjectSvDraw::CreateThumb( const FmFormModel
& rModel
)
450 if ( CreateIMapGraphic( rModel
, aGraphic
, aImageMap
) )
452 bRet
= SgaObject::CreateThumb( aGraphic
);
456 const FmFormPage
* pPage
= static_cast< const FmFormPage
* >(rModel
.GetPage(0));
460 const tools::Rectangle
aObjRect(pPage
->GetAllObjBoundRect());
462 if(aObjRect
.GetWidth() && aObjRect
.GetHeight())
464 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
465 FmFormView
aView(const_cast< FmFormModel
& >(rModel
), pVDev
);
467 aView
.ShowSdrPage(const_cast< FmFormPage
* >(pPage
));
469 aThumbBmp
= aView
.GetMarkedObjBitmapEx(true);
470 aGraphic
= Graphic(aThumbBmp
);
471 bRet
= SgaObject::CreateThumb(aGraphic
);
479 void SgaObjectSvDraw::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
481 SgaObject::WriteData( rOut
, rDestDir
);
482 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
485 void SgaObjectSvDraw::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
487 SgaObject::ReadData( rIn
, rReadVersion
);
489 if( rReadVersion
>= 5 )
490 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */