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 <com/sun/star/lang/XUnoTunnel.hpp>
24 #include <sfx2/objsh.hxx>
25 #include <comphelper/fileformat.h>
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 "gallerydrawmodel.hxx"
36 #include <bitmaps.hlst>
38 using namespace ::com::sun::star
;
40 SgaObject::SgaObject()
46 SgaObject::SgaObject(const SgaObject
& aObject
)
47 : aThumbBmp(aObject
.aThumbBmp
)
48 , aThumbMtf(aObject
.aThumbMtf
)
50 , aTitle(aObject
.aTitle
)
51 , bIsValid(aObject
.bIsValid
)
52 , bIsThumbBmp(aObject
.bIsThumbBmp
)
56 BitmapEx
SgaObject::createPreviewBitmapEx(const Size
& rSizePixel
) const
60 if(rSizePixel
.Width() && rSizePixel
.Height())
62 if(SgaObjKind::Sound
== GetObjKind())
64 aRetval
= BitmapEx(RID_SVXBMP_GALLERY_MEDIA
);
66 else if(IsThumbBitmap())
68 aRetval
= GetThumbBmp();
72 const Graphic
aGraphic(GetThumbMtf());
74 aRetval
= aGraphic
.GetBitmapEx();
77 if(!aRetval
.IsEmpty())
79 const Size
aCurrentSizePixel(aRetval
.GetSizePixel());
80 const double fScaleX(static_cast<double>(rSizePixel
.Width()) / static_cast<double>(aCurrentSizePixel
.Width()));
81 const double fScaleY(static_cast<double>(rSizePixel
.Height()) / static_cast<double>(aCurrentSizePixel
.Height()));
82 const double fScale(std::min(fScaleX
, fScaleY
));
84 // only scale when need to decrease, no need to make bigger as original. Also
85 // prevent scaling close to 1.0 which is not needed for pixel graphics
86 if(fScale
< 1.0 && fabs(1.0 - fScale
) > 0.005)
88 aRetval
.Scale(fScale
, fScale
, BmpScaleFlag::BestQuality
);
96 bool SgaObject::CreateThumb( const Graphic
& rGraphic
)
100 if( rGraphic
.GetType() == GraphicType::Bitmap
)
102 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
103 Size
aBmpSize( aBmpEx
.GetSizePixel() );
105 if( aBmpSize
.Width() && aBmpSize
.Height() )
107 if( aBmpEx
.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel
&&
108 aBmpEx
.GetPrefSize().Width() > 0 &&
109 aBmpEx
.GetPrefSize().Height() > 0 )
111 Size
aLogSize( OutputDevice::LogicToLogic(aBmpEx
.GetPrefSize(), aBmpEx
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
)) );
113 if( !aLogSize
.IsEmpty() )
115 double fFactorLog
= static_cast< double >( aLogSize
.Width() ) / aLogSize
.Height();
116 double fFactorPix
= static_cast< double >( aBmpSize
.Width() ) / aBmpSize
.Height();
118 if( fFactorPix
> fFactorLog
)
119 aBmpSize
.setWidth( FRound( aBmpSize
.Height() * fFactorLog
) );
121 aBmpSize
.setHeight( FRound( aBmpSize
.Width() / fFactorLog
) );
123 aBmpEx
.Scale(aBmpSize
, BmpScaleFlag::BestQuality
);
127 // take over BitmapEx
130 if( ( aBmpSize
.Width() <= S_THUMB
) && ( aBmpSize
.Height() <= S_THUMB
) )
132 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
137 const float fFactor
= static_cast<float>(aBmpSize
.Width()) / aBmpSize
.Height();
138 const Size
aNewSize( std::max( tools::Long(fFactor
< 1. ? S_THUMB
* fFactor
: S_THUMB
), tools::Long(8) ),
139 std::max( tools::Long(fFactor
< 1. ? S_THUMB
: S_THUMB
/ fFactor
), tools::Long(8) ) );
141 static_cast<double>(aNewSize
.Width()) / aBmpSize
.Width(),
142 static_cast<double>(aNewSize
.Height()) / aBmpSize
.Height(),
143 BmpScaleFlag::BestQuality
) )
145 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
151 else if( rGraphic
.GetType() == GraphicType::GdiMetafile
)
153 const Size
aPrefSize( rGraphic
.GetPrefSize() );
154 const double fFactor
= static_cast<double>(aPrefSize
.Width()) / static_cast<double>(aPrefSize
.Height());
155 Size
aSize( S_THUMB
, S_THUMB
);
157 aSize
.setWidth( static_cast<sal_Int32
>( S_THUMB
* fFactor
) );
159 aSize
.setHeight( static_cast<sal_Int32
>( S_THUMB
/ fFactor
) );
161 const GraphicConversionParameters
aParameters(aSize
, false, true, true /*TODO: extra ", true" post-#i121194#*/);
162 aThumbBmp
= rGraphic
.GetBitmapEx(aParameters
);
164 if( !aThumbBmp
.IsEmpty() )
166 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
174 void SgaObject::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
176 static const sal_uInt32 nInventor
= COMPAT_FORMAT( 'S', 'G', 'A', '3' );
178 rOut
.WriteUInt32( nInventor
).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( static_cast<sal_uInt16
>(GetObjKind()) );
179 rOut
.WriteBool( bIsThumbBmp
);
183 const SvStreamCompressFlags nOldCompressMode
= rOut
.GetCompressMode();
184 const sal_Int32 nOldVersion
= rOut
.GetVersion();
186 rOut
.SetCompressMode( SvStreamCompressFlags::ZBITMAP
);
187 rOut
.SetVersion( SOFFICE_FILEFORMAT_50
);
189 WriteDIBBitmapEx(aThumbBmp
, rOut
);
191 rOut
.SetVersion( nOldVersion
);
192 rOut
.SetCompressMode( nOldCompressMode
);
195 WriteGDIMetaFile( rOut
, aThumbMtf
);
197 OUString aURLWithoutDestDir
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
198 aURLWithoutDestDir
= aURLWithoutDestDir
.replaceFirst(rDestDir
, "");
199 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aURLWithoutDestDir
, RTL_TEXTENCODING_UTF8
);
202 void SgaObject::ReadData(SvStream
& rIn
, sal_uInt16
& rReadVersion
)
207 rIn
.ReadUInt32( nTmp32
).ReadUInt16( nTmp16
).ReadUInt16( rReadVersion
).ReadUInt16( nTmp16
).ReadCharAsBool( bIsThumbBmp
);
211 ReadDIBBitmapEx(aThumbBmp
, rIn
);
215 ReadGDIMetaFile( rIn
, aThumbMtf
);
218 OUString aTmpStr
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
219 aURL
= INetURLObject(aTmpStr
);
222 OUString
const & SgaObject::GetTitle() const
227 void SgaObject::SetTitle( const OUString
& rTitle
)
232 SvStream
& WriteSgaObject( SvStream
& rOut
, const SgaObject
& rObj
)
234 rObj
.WriteData( rOut
, "" );
238 SvStream
& ReadSgaObject( SvStream
& rIn
, SgaObject
& rObj
)
240 sal_uInt16 nReadVersion
;
242 rObj
.ReadData( rIn
, nReadVersion
);
243 rObj
.bIsValid
= ( rIn
.GetError() == ERRCODE_NONE
);
248 SgaObjectBmp::SgaObjectBmp()
252 SgaObjectBmp::SgaObjectBmp( const INetURLObject
& rURL
)
257 if ( GalleryGraphicImportRet::IMPORT_NONE
!= GalleryGraphicImport( rURL
, aGraphic
, aFilter
) )
258 Init( aGraphic
, rURL
);
261 SgaObjectBmp::SgaObjectBmp( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
263 if( FileExists( rURL
) )
264 Init( rGraphic
, rURL
);
267 void SgaObjectBmp::Init( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
270 bIsValid
= CreateThumb( rGraphic
);
273 void SgaObjectBmp::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
276 SgaObject::WriteData( rOut
, rDestDir
);
277 char const aDummy
[ 10 ] = { 0 };
278 rOut
.WriteBytes(aDummy
, 10);
279 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut
, ""); //dummy
280 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
283 void SgaObjectBmp::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
286 SgaObject::ReadData( rIn
, rReadVersion
);
287 rIn
.SeekRel( 10 ); // 16, 16, 32, 16
288 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn
); //dummy
290 if( rReadVersion
>= 5 )
291 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
295 SgaObjectSound::SgaObjectSound() :
296 eSoundType( SOUND_STANDARD
)
300 SgaObjectSound::SgaObjectSound( const INetURLObject
& rURL
) :
301 eSoundType( SOUND_STANDARD
)
304 if( FileExists( rURL
) )
307 aThumbBmp
= Bitmap(Size(1, 1), vcl::PixelFormat::N1_BPP
);
314 SgaObjectSound::~SgaObjectSound()
318 BitmapEx
SgaObjectSound::GetThumbBmp() const
324 case SOUND_COMPUTER
: sId
= RID_SVXBMP_GALLERY_SOUND_1
; break;
325 case SOUND_MISC
: sId
= RID_SVXBMP_GALLERY_SOUND_2
; break;
326 case SOUND_MUSIC
: sId
= RID_SVXBMP_GALLERY_SOUND_3
; break;
327 case SOUND_NATURE
: sId
= RID_SVXBMP_GALLERY_SOUND_4
; break;
328 case SOUND_SPEECH
: sId
= RID_SVXBMP_GALLERY_SOUND_5
; break;
329 case SOUND_TECHNIC
: sId
= RID_SVXBMP_GALLERY_SOUND_6
; break;
330 case SOUND_ANIMAL
: sId
= RID_SVXBMP_GALLERY_SOUND_7
; break;
334 sId
= RID_SVXBMP_GALLERY_MEDIA
;
338 const BitmapEx
aBmpEx(sId
);
343 void SgaObjectSound::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
345 SgaObject::WriteData( rOut
, rDestDir
);
346 rOut
.WriteUInt16( eSoundType
);
347 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
350 void SgaObjectSound::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
352 SgaObject::ReadData( rIn
, rReadVersion
);
354 if( rReadVersion
>= 5 )
358 rIn
.ReadUInt16( nTmp16
); eSoundType
= static_cast<GalSoundType
>(nTmp16
);
360 if( rReadVersion
>= 6 )
361 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
365 SgaObjectAnim::SgaObjectAnim()
369 SgaObjectAnim::SgaObjectAnim( const Graphic
& rGraphic
,
370 const INetURLObject
& rURL
)
373 bIsValid
= CreateThumb( rGraphic
);
376 SgaObjectINet::SgaObjectINet()
380 SgaObjectINet::SgaObjectINet( const Graphic
& rGraphic
, const INetURLObject
& rURL
) :
381 SgaObjectAnim ( rGraphic
, rURL
)
385 SgaObjectSvDraw::SgaObjectSvDraw()
389 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel
& rModel
, const INetURLObject
& rURL
)
392 bIsValid
= CreateThumb( rModel
);
396 SvxGalleryDrawModel::SvxGalleryDrawModel()
397 : mpFormModel( nullptr )
399 mxDoc
= SfxObjectShell::CreateObjectByFactoryName( "sdraw" );
406 uno::Reference
< lang::XUnoTunnel
> xTunnel( mxDoc
->GetModel(), uno::UNO_QUERY
);
409 mpFormModel
= dynamic_cast< FmFormModel
* >(
410 reinterpret_cast<SdrModel
*>(xTunnel
->getSomething(SdrModel::getUnoTunnelId())));
413 mpFormModel
->InsertPage( mpFormModel
->AllocPage( false ).get() );
418 SvxGalleryDrawModel::~SvxGalleryDrawModel()
425 SgaObjectSvDraw::SgaObjectSvDraw( SvStream
& rIStm
, const INetURLObject
& rURL
)
427 SvxGalleryDrawModel aModel
;
429 if( aModel
.GetModel() )
431 if( GallerySvDrawImport( rIStm
, *aModel
.GetModel() ) )
434 bIsValid
= CreateThumb( *aModel
.GetModel() );
439 bool SgaObjectSvDraw::CreateThumb( const FmFormModel
& rModel
)
445 if ( CreateIMapGraphic( rModel
, aGraphic
, aImageMap
) )
447 bRet
= SgaObject::CreateThumb( aGraphic
);
451 const FmFormPage
* pPage
= static_cast< const FmFormPage
* >(rModel
.GetPage(0));
455 const tools::Rectangle
aObjRect(pPage
->GetAllObjBoundRect());
457 if(aObjRect
.GetWidth() && aObjRect
.GetHeight())
459 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
460 FmFormView
aView(const_cast< FmFormModel
& >(rModel
), pVDev
);
462 aView
.ShowSdrPage(const_cast< FmFormPage
* >(pPage
));
464 aThumbBmp
= aView
.GetMarkedObjBitmapEx(true);
465 aGraphic
= Graphic(aThumbBmp
);
466 bRet
= SgaObject::CreateThumb(aGraphic
);
474 void SgaObjectSvDraw::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
476 SgaObject::WriteData( rOut
, rDestDir
);
477 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
480 void SgaObjectSvDraw::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
482 SgaObject::ReadData( rIn
, rReadVersion
);
484 if( rReadVersion
>= 5 )
485 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
488 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */