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/classids.hxx>
25 #include <comphelper/string.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <tools/rcid.h>
28 #include <tools/resmgr.hxx>
29 #include <tools/vcompat.hxx>
30 #include <tools/helpers.hxx>
31 #include <vcl/virdev.hxx>
32 #include <svl/itempool.hxx>
33 #include <svx/fmmodel.hxx>
34 #include <svx/fmview.hxx>
35 #include <svx/fmpage.hxx>
36 #include "gallery.hrc"
37 #include "svx/galmisc.hxx"
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <vcl/dibtools.hxx>
42 #include "gallerydrawmodel.hxx"
44 #include "bitmaps.hlst"
46 using namespace ::com::sun::star
;
48 SgaObject::SgaObject()
54 BitmapEx
SgaObject::createPreviewBitmapEx(const Size
& rSizePixel
) const
58 if(rSizePixel
.Width() && rSizePixel
.Height())
60 if(SgaObjKind::Sound
== GetObjKind())
62 aRetval
= BitmapEx(RID_SVXBMP_GALLERY_MEDIA
);
64 else if(IsThumbBitmap())
66 aRetval
= GetThumbBmp();
70 const Graphic
aGraphic(GetThumbMtf());
72 aRetval
= aGraphic
.GetBitmapEx();
75 if(!aRetval
.IsEmpty())
77 const Size
aCurrentSizePixel(aRetval
.GetSizePixel());
78 const double fScaleX((double)rSizePixel
.Width() / (double)aCurrentSizePixel
.Width());
79 const double fScaleY((double)rSizePixel
.Height() / (double)aCurrentSizePixel
.Height());
80 const double fScale(std::min(fScaleX
, fScaleY
));
82 // only scale when need to decrease, no need to make bigger as original. Also
83 // prevent scaling close to 1.0 which is not needed for pixel graphics
84 if(fScale
< 1.0 && fabs(1.0 - fScale
) > 0.005)
86 aRetval
.Scale(fScale
, fScale
, BmpScaleFlag::BestQuality
);
94 bool SgaObject::CreateThumb( const Graphic
& rGraphic
)
98 if( rGraphic
.GetType() == GraphicType::Bitmap
)
100 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
101 Size
aBmpSize( aBmpEx
.GetSizePixel() );
103 if( aBmpSize
.Width() && aBmpSize
.Height() )
105 if( aBmpEx
.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel
&&
106 aBmpEx
.GetPrefSize().Width() > 0 &&
107 aBmpEx
.GetPrefSize().Height() > 0 )
109 Size
aLogSize( OutputDevice::LogicToLogic( aBmpEx
.GetPrefSize(), aBmpEx
.GetPrefMapMode(), MapUnit::Map100thMM
) );
111 if( aLogSize
.Width() > 0 && aLogSize
.Height() > 0 )
113 double fFactorLog
= static_cast< double >( aLogSize
.Width() ) / aLogSize
.Height();
114 double fFactorPix
= static_cast< double >( aBmpSize
.Width() ) / aBmpSize
.Height();
116 if( fFactorPix
> fFactorLog
)
117 aBmpSize
.Width() = FRound( aBmpSize
.Height() * fFactorLog
);
119 aBmpSize
.Height() = FRound( aBmpSize
.Width() / fFactorLog
);
121 aBmpEx
.SetSizePixel( aBmpSize
, BmpScaleFlag::BestQuality
);
125 // take over BitmapEx
128 if( ( aBmpSize
.Width() <= S_THUMB
) && ( aBmpSize
.Height() <= S_THUMB
) )
130 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
135 const float fFactor
= (float) aBmpSize
.Width() / aBmpSize
.Height();
136 const Size
aNewSize( std::max( (long) (fFactor
< 1. ? S_THUMB
* fFactor
: S_THUMB
), 8L ),
137 std::max( (long) (fFactor
< 1. ? S_THUMB
: S_THUMB
/ fFactor
), 8L ) );
139 (double) aNewSize
.Width() / aBmpSize
.Width(),
140 (double) aNewSize
.Height() / aBmpSize
.Height(),
141 BmpScaleFlag::BestQuality
) )
143 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
149 else if( rGraphic
.GetType() == GraphicType::GdiMetafile
)
151 const Size
aPrefSize( rGraphic
.GetPrefSize() );
152 const double fFactor
= (double)aPrefSize
.Width() / (double)aPrefSize
.Height();
153 Size
aSize( S_THUMB
, S_THUMB
);
155 aSize
.Width() = (sal_Int32
)( S_THUMB
* fFactor
);
157 aSize
.Height() = (sal_Int32
)( S_THUMB
/ fFactor
);
159 const GraphicConversionParameters
aParameters(aSize
, false, true, true /*TODO: extra ", true" post-#i121194#*/);
160 aThumbBmp
= rGraphic
.GetBitmapEx(aParameters
);
162 if( !aThumbBmp
.IsEmpty() )
164 aThumbBmp
.Convert( BmpConversion::N8BitColors
);
172 void SgaObject::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
174 static const sal_uInt32 nInventor
= COMPAT_FORMAT( 'S', 'G', 'A', '3' );
176 rOut
.WriteUInt32( nInventor
).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( (sal_uInt16
)GetObjKind() );
177 rOut
.WriteBool( bIsThumbBmp
);
181 const SvStreamCompressFlags nOldCompressMode
= rOut
.GetCompressMode();
182 const sal_uIntPtr nOldVersion
= rOut
.GetVersion();
184 rOut
.SetCompressMode( SvStreamCompressFlags::ZBITMAP
);
185 rOut
.SetVersion( SOFFICE_FILEFORMAT_50
);
187 WriteDIBBitmapEx(aThumbBmp
, rOut
);
189 rOut
.SetVersion( nOldVersion
);
190 rOut
.SetCompressMode( nOldCompressMode
);
193 WriteGDIMetaFile( rOut
, aThumbMtf
);
195 OUString aURLWithoutDestDir
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
196 aURLWithoutDestDir
= aURLWithoutDestDir
.replaceFirst(rDestDir
, "");
197 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aURLWithoutDestDir
, RTL_TEXTENCODING_UTF8
);
200 void SgaObject::ReadData(SvStream
& rIn
, sal_uInt16
& rReadVersion
)
205 rIn
.ReadUInt32( nTmp32
).ReadUInt16( nTmp16
).ReadUInt16( rReadVersion
).ReadUInt16( nTmp16
).ReadCharAsBool( bIsThumbBmp
);
209 ReadDIBBitmapEx(aThumbBmp
, rIn
);
213 ReadGDIMetaFile( rIn
, aThumbMtf
);
216 OUString aTmpStr
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
217 aURL
= INetURLObject(aTmpStr
);
220 const OUString
SgaObject::GetTitle() const
222 OUString
aReturnValue( aTitle
);
223 if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
225 if ( comphelper::string::getTokenCount(aReturnValue
, ':') == 3 )
227 OUString
aPrivateInd ( aReturnValue
.getToken( 0, ':' ) );
228 OUString
aResourceName( aReturnValue
.getToken( 1, ':' ) );
229 sal_Int32
nResId ( aReturnValue
.getToken( 2, ':' ).toInt32() );
230 if ( aPrivateInd
== "private" &&
231 !aResourceName
.isEmpty() && ( nResId
> 0 ) && ( nResId
< 0x10000 ) )
233 OString
aMgrName(OUStringToOString(aResourceName
, RTL_TEXTENCODING_UTF8
));
234 std::unique_ptr
<ResMgr
> pResMgr(ResMgr::CreateResMgr( aMgrName
.getStr(),
235 Application::GetSettings().GetUILanguageTag() ));
238 ResId
aResId( (sal_uInt16
)nResId
, *pResMgr
);
239 aResId
.SetRT( RSC_STRING
);
240 if ( pResMgr
->IsAvailable( aResId
) )
242 aReturnValue
= aResId
;
251 void SgaObject::SetTitle( const OUString
& rTitle
)
256 SvStream
& WriteSgaObject( SvStream
& rOut
, const SgaObject
& rObj
)
258 rObj
.WriteData( rOut
, "" );
262 SvStream
& ReadSgaObject( SvStream
& rIn
, SgaObject
& rObj
)
264 sal_uInt16 nReadVersion
;
266 rObj
.ReadData( rIn
, nReadVersion
);
267 rObj
.bIsValid
= ( rIn
.GetError() == ERRCODE_NONE
);
272 SgaObjectBmp::SgaObjectBmp()
276 SgaObjectBmp::SgaObjectBmp( const INetURLObject
& rURL
)
281 if ( GalleryGraphicImportRet::IMPORT_NONE
!= GalleryGraphicImport( rURL
, aGraphic
, aFilter
) )
282 Init( aGraphic
, rURL
);
285 SgaObjectBmp::SgaObjectBmp( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
287 if( FileExists( rURL
) )
288 Init( rGraphic
, rURL
);
291 void SgaObjectBmp::Init( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
294 bIsValid
= CreateThumb( rGraphic
);
297 void SgaObjectBmp::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
300 SgaObject::WriteData( rOut
, rDestDir
);
301 char aDummy
[ 10 ] = { 0 };
302 rOut
.WriteBytes(aDummy
, 10);
303 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut
, OString()); //dummy
304 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
307 void SgaObjectBmp::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
310 SgaObject::ReadData( rIn
, rReadVersion
);
311 rIn
.SeekRel( 10 ); // 16, 16, 32, 16
312 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn
); //dummy
314 if( rReadVersion
>= 5 )
315 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
319 SgaObjectSound::SgaObjectSound() :
320 eSoundType( SOUND_STANDARD
)
324 SgaObjectSound::SgaObjectSound( const INetURLObject
& rURL
) :
325 eSoundType( SOUND_STANDARD
)
328 if( FileExists( rURL
) )
331 aThumbBmp
= Bitmap( Size( 1, 1 ), 1 );
338 SgaObjectSound::~SgaObjectSound()
342 BitmapEx
SgaObjectSound::GetThumbBmp() const
348 case SOUND_COMPUTER
: sId
= RID_SVXBMP_GALLERY_SOUND_1
; break;
349 case SOUND_MISC
: sId
= RID_SVXBMP_GALLERY_SOUND_2
; break;
350 case SOUND_MUSIC
: sId
= RID_SVXBMP_GALLERY_SOUND_3
; break;
351 case SOUND_NATURE
: sId
= RID_SVXBMP_GALLERY_SOUND_4
; break;
352 case SOUND_SPEECH
: sId
= RID_SVXBMP_GALLERY_SOUND_5
; break;
353 case SOUND_TECHNIC
: sId
= RID_SVXBMP_GALLERY_SOUND_6
; break;
354 case SOUND_ANIMAL
: sId
= RID_SVXBMP_GALLERY_SOUND_7
; break;
358 sId
= RID_SVXBMP_GALLERY_MEDIA
;
362 const BitmapEx
aBmpEx(sId
);
367 void SgaObjectSound::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
369 SgaObject::WriteData( rOut
, rDestDir
);
370 rOut
.WriteUInt16( eSoundType
);
371 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
374 void SgaObjectSound::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
376 SgaObject::ReadData( rIn
, rReadVersion
);
378 if( rReadVersion
>= 5 )
382 rIn
.ReadUInt16( nTmp16
); eSoundType
= (GalSoundType
) nTmp16
;
384 if( rReadVersion
>= 6 )
385 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
389 SgaObjectAnim::SgaObjectAnim()
393 SgaObjectAnim::SgaObjectAnim( const Graphic
& rGraphic
,
394 const INetURLObject
& rURL
)
397 bIsValid
= CreateThumb( rGraphic
);
400 SgaObjectINet::SgaObjectINet()
404 SgaObjectINet::SgaObjectINet( const Graphic
& rGraphic
, const INetURLObject
& rURL
) :
405 SgaObjectAnim ( rGraphic
, rURL
)
409 SgaObjectSvDraw::SgaObjectSvDraw()
413 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel
& rModel
, const INetURLObject
& rURL
)
416 bIsValid
= CreateThumb( rModel
);
420 SvxGalleryDrawModel::SvxGalleryDrawModel()
421 : mpFormModel( nullptr )
424 const OUString
sFactoryURL("sdraw");
426 mxDoc
= SfxObjectShell::CreateObjectByFactoryName( sFactoryURL
);
432 uno::Reference
< lang::XUnoTunnel
> xTunnel( mxDoc
->GetModel(), uno::UNO_QUERY
);
435 mpFormModel
= dynamic_cast< FmFormModel
* >(
436 reinterpret_cast<SdrModel
*>(xTunnel
->getSomething(SdrModel::getUnoTunnelImplementationId())));
439 mpFormModel
->InsertPage( mpFormModel
->AllocPage( false ) );
445 SvxGalleryDrawModel::~SvxGalleryDrawModel()
452 SgaObjectSvDraw::SgaObjectSvDraw( SvStream
& rIStm
, const INetURLObject
& rURL
)
454 SvxGalleryDrawModel aModel
;
456 if( aModel
.GetModel() )
458 if( GallerySvDrawImport( rIStm
, *aModel
.GetModel() ) )
461 bIsValid
= CreateThumb( *aModel
.GetModel() );
466 bool SgaObjectSvDraw::CreateThumb( const FmFormModel
& rModel
)
472 if ( CreateIMapGraphic( rModel
, aGraphic
, aImageMap
) )
474 bRet
= SgaObject::CreateThumb( aGraphic
);
478 const FmFormPage
* pPage
= static_cast< const FmFormPage
* >(rModel
.GetPage(0));
482 const tools::Rectangle
aObjRect(pPage
->GetAllObjBoundRect());
484 if(aObjRect
.GetWidth() && aObjRect
.GetHeight())
486 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
487 FmFormView
aView(const_cast< FmFormModel
* >(&rModel
), pVDev
);
489 aView
.ShowSdrPage(const_cast< FmFormPage
* >(pPage
));
491 aThumbBmp
= aView
.GetMarkedObjBitmapEx();
493 const Size
aDiscreteSize(aThumbBmp
.GetSizePixel());
495 if(aDiscreteSize
.Width() && aDiscreteSize
.Height())
497 sal_uInt32
nTargetSizeX(S_THUMB
);
498 sal_uInt32
nTargetSizeY(S_THUMB
);
500 if(aDiscreteSize
.Width() > aDiscreteSize
.Height())
502 nTargetSizeY
= (aDiscreteSize
.Height() * nTargetSizeX
) / aDiscreteSize
.Width();
506 nTargetSizeX
= (aDiscreteSize
.Width() * nTargetSizeY
) / aDiscreteSize
.Height();
511 aThumbBmp
.Scale(Size(nTargetSizeX
, nTargetSizeY
), BmpScaleFlag::BestQuality
);
512 aThumbBmp
.Convert(BmpConversion::N8BitColors
);
523 void SgaObjectSvDraw::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
525 SgaObject::WriteData( rOut
, rDestDir
);
526 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
529 void SgaObjectSvDraw::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
531 SgaObject::ReadData( rIn
, rReadVersion
);
533 if( rReadVersion
>= 5 )
534 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */