LibreOffice Module svx (master)  1
galobj.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
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>
33 #include <galobj.hxx>
34 #include <vcl/dibtools.hxx>
35 #include "gallerydrawmodel.hxx"
36 #include <bitmaps.hlst>
37 
38 using namespace ::com::sun::star;
39 
40 SgaObject::SgaObject()
41 : bIsValid ( false ),
42  bIsThumbBmp ( true )
43 {
44 }
45 
46 BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const
47 {
48  BitmapEx aRetval;
49 
50  if(rSizePixel.Width() && rSizePixel.Height())
51  {
52  if(SgaObjKind::Sound == GetObjKind())
53  {
54  aRetval = BitmapEx(RID_SVXBMP_GALLERY_MEDIA);
55  }
56  else if(IsThumbBitmap())
57  {
58  aRetval = GetThumbBmp();
59  }
60  else
61  {
62  const Graphic aGraphic(GetThumbMtf());
63 
64  aRetval = aGraphic.GetBitmapEx();
65  }
66 
67  if(!aRetval.IsEmpty())
68  {
69  const Size aCurrentSizePixel(aRetval.GetSizePixel());
70  const double fScaleX(static_cast<double>(rSizePixel.Width()) / static_cast<double>(aCurrentSizePixel.Width()));
71  const double fScaleY(static_cast<double>(rSizePixel.Height()) / static_cast<double>(aCurrentSizePixel.Height()));
72  const double fScale(std::min(fScaleX, fScaleY));
73 
74  // only scale when need to decrease, no need to make bigger as original. Also
75  // prevent scaling close to 1.0 which is not needed for pixel graphics
76  if(fScale < 1.0 && fabs(1.0 - fScale) > 0.005)
77  {
78  aRetval.Scale(fScale, fScale, BmpScaleFlag::BestQuality);
79  }
80  }
81  }
82 
83  return aRetval;
84 }
85 
86 bool SgaObject::CreateThumb( const Graphic& rGraphic )
87 {
88  bool bRet = false;
89 
90  if( rGraphic.GetType() == GraphicType::Bitmap )
91  {
92  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
93  Size aBmpSize( aBmpEx.GetSizePixel() );
94 
95  if( aBmpSize.Width() && aBmpSize.Height() )
96  {
97  if( aBmpEx.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel &&
98  aBmpEx.GetPrefSize().Width() > 0 &&
99  aBmpEx.GetPrefSize().Height() > 0 )
100  {
101  Size aLogSize( OutputDevice::LogicToLogic(aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
102 
103  if( !aLogSize.IsEmpty() )
104  {
105  double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
106  double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
107 
108  if( fFactorPix > fFactorLog )
109  aBmpSize.setWidth( FRound( aBmpSize.Height() * fFactorLog ) );
110  else
111  aBmpSize.setHeight( FRound( aBmpSize.Width() / fFactorLog ) );
112 
113  aBmpEx.Scale(aBmpSize, BmpScaleFlag::BestQuality);
114  }
115  }
116 
117  // take over BitmapEx
118  aThumbBmp = aBmpEx;
119 
120  if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
121  {
122  aThumbBmp.Convert( BmpConversion::N8BitColors );
123  bRet = true;
124  }
125  else
126  {
127  const float fFactor = static_cast<float>(aBmpSize.Width()) / aBmpSize.Height();
128  const Size aNewSize( std::max( static_cast<long>(fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
129  std::max( static_cast<long>(fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
130  if(aThumbBmp.Scale(
131  static_cast<double>(aNewSize.Width()) / aBmpSize.Width(),
132  static_cast<double>(aNewSize.Height()) / aBmpSize.Height(),
133  BmpScaleFlag::BestQuality ) )
134  {
135  aThumbBmp.Convert( BmpConversion::N8BitColors );
136  bRet = true;
137  }
138  }
139  }
140  }
141  else if( rGraphic.GetType() == GraphicType::GdiMetafile )
142  {
143  const Size aPrefSize( rGraphic.GetPrefSize() );
144  const double fFactor = static_cast<double>(aPrefSize.Width()) / static_cast<double>(aPrefSize.Height());
145  Size aSize( S_THUMB, S_THUMB );
146  if ( fFactor < 1.0 )
147  aSize.setWidth( static_cast<sal_Int32>( S_THUMB * fFactor ) );
148  else
149  aSize.setHeight( static_cast<sal_Int32>( S_THUMB / fFactor ) );
150 
151  const GraphicConversionParameters aParameters(aSize, false, true, true /*TODO: extra ", true" post-#i121194#*/);
152  aThumbBmp = rGraphic.GetBitmapEx(aParameters);
153 
154  if( !aThumbBmp.IsEmpty() )
155  {
156  aThumbBmp.Convert( BmpConversion::N8BitColors );
157  bRet = true;
158  }
159  }
160 
161  return bRet;
162 }
163 
164 void SgaObject::WriteData( SvStream& rOut, const OUString& rDestDir ) const
165 {
166  static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
167 
168  rOut.WriteUInt32( nInventor ).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( static_cast<sal_uInt16>(GetObjKind()) );
169  rOut.WriteBool( bIsThumbBmp );
170 
171  if( bIsThumbBmp )
172  {
173  const SvStreamCompressFlags nOldCompressMode = rOut.GetCompressMode();
174  const sal_Int32 nOldVersion = rOut.GetVersion();
175 
176  rOut.SetCompressMode( SvStreamCompressFlags::ZBITMAP );
177  rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
178 
179  WriteDIBBitmapEx(aThumbBmp, rOut);
180 
181  rOut.SetVersion( nOldVersion );
182  rOut.SetCompressMode( nOldCompressMode );
183  }
184  else
185  WriteGDIMetaFile( rOut, aThumbMtf );
186 
187  OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
188  aURLWithoutDestDir = aURLWithoutDestDir.replaceFirst(rDestDir, "");
189  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aURLWithoutDestDir, RTL_TEXTENCODING_UTF8);
190 }
191 
192 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
193 {
194  sal_uInt32 nTmp32;
195  sal_uInt16 nTmp16;
196 
197  rIn.ReadUInt32( nTmp32 ).ReadUInt16( nTmp16 ).ReadUInt16( rReadVersion ).ReadUInt16( nTmp16 ).ReadCharAsBool( bIsThumbBmp );
198 
199  if( bIsThumbBmp )
200  {
201  ReadDIBBitmapEx(aThumbBmp, rIn);
202  }
203  else
204  {
205  ReadGDIMetaFile( rIn, aThumbMtf );
206  }
207 
208  OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
209  aURL = INetURLObject(aTmpStr);
210 }
211 
212 OUString const & SgaObject::GetTitle() const
213 {
214  return aTitle;
215 }
216 
217 void SgaObject::SetTitle( const OUString& rTitle )
218 {
219  aTitle = rTitle;
220 }
221 
222 SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj )
223 {
224  rObj.WriteData( rOut, "" );
225  return rOut;
226 }
227 
228 SvStream& ReadSgaObject( SvStream& rIn, SgaObject& rObj )
229 {
230  sal_uInt16 nReadVersion;
231 
232  rObj.ReadData( rIn, nReadVersion );
233  rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
234 
235  return rIn;
236 }
237 
239 {
240 }
241 
243 {
244  Graphic aGraphic;
245  OUString aFilter;
246 
247  if ( GalleryGraphicImportRet::IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
248  Init( aGraphic, rURL );
249 }
250 
251 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL )
252 {
253  if( FileExists( rURL ) )
254  Init( rGraphic, rURL );
255 }
256 
257 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
258 {
259  aURL = rURL;
260  bIsValid = CreateThumb( rGraphic );
261 }
262 
263 void SgaObjectBmp::WriteData( SvStream& rOut, const OUString& rDestDir ) const
264 {
265  // Set version
266  SgaObject::WriteData( rOut, rDestDir );
267  char const aDummy[ 10 ] = { 0 };
268  rOut.WriteBytes(aDummy, 10);
269  write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, OString()); //dummy
270  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
271 }
272 
273 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
274 {
275 
276  SgaObject::ReadData( rIn, rReadVersion );
277  rIn.SeekRel( 10 ); // 16, 16, 32, 16
279 
280  if( rReadVersion >= 5 )
281  aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
282 }
283 
284 
286  eSoundType( SOUND_STANDARD )
287 {
288 }
289 
291  eSoundType( SOUND_STANDARD )
292 {
293 
294  if( FileExists( rURL ) )
295  {
296  aURL = rURL;
297  aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
298  bIsValid = true;
299  }
300  else
301  bIsValid = false;
302 }
303 
305 {
306 }
307 
309 {
310  OUString sId;
311 
312  switch( eSoundType )
313  {
314  case SOUND_COMPUTER: sId = RID_SVXBMP_GALLERY_SOUND_1; break;
315  case SOUND_MISC: sId = RID_SVXBMP_GALLERY_SOUND_2; break;
316  case SOUND_MUSIC: sId = RID_SVXBMP_GALLERY_SOUND_3; break;
317  case SOUND_NATURE: sId = RID_SVXBMP_GALLERY_SOUND_4; break;
318  case SOUND_SPEECH: sId = RID_SVXBMP_GALLERY_SOUND_5; break;
319  case SOUND_TECHNIC: sId = RID_SVXBMP_GALLERY_SOUND_6; break;
320  case SOUND_ANIMAL: sId = RID_SVXBMP_GALLERY_SOUND_7; break;
321 
322  // standard
323  default:
324  sId = RID_SVXBMP_GALLERY_MEDIA;
325  break;
326  }
327 
328  const BitmapEx aBmpEx(sId);
329 
330  return aBmpEx;
331 }
332 
333 void SgaObjectSound::WriteData( SvStream& rOut, const OUString& rDestDir ) const
334 {
335  SgaObject::WriteData( rOut, rDestDir );
336  rOut.WriteUInt16( eSoundType );
337  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
338 }
339 
340 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
341 {
342  SgaObject::ReadData( rIn, rReadVersion );
343 
344  if( rReadVersion >= 5 )
345  {
346  sal_uInt16 nTmp16;
347 
348  rIn.ReadUInt16( nTmp16 ); eSoundType = static_cast<GalSoundType>(nTmp16);
349 
350  if( rReadVersion >= 6 )
351  aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
352  }
353 }
354 
356 {
357 }
358 
360  const INetURLObject& rURL )
361 {
362  aURL = rURL;
363  bIsValid = CreateThumb( rGraphic );
364 }
365 
367 {
368 }
369 
370 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL ) :
371  SgaObjectAnim ( rGraphic, rURL )
372 {
373 }
374 
376 {
377 }
378 
380 {
381  aURL = rURL;
382  bIsValid = CreateThumb( rModel );
383 }
384 
385 
387 : mpFormModel( nullptr )
388 {
390 
391  if( mxDoc.Is() )
392  {
393  mxDoc->DoInitNew();
394 
395  uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
396  if( xTunnel.is() )
397  {
398  mpFormModel = dynamic_cast< FmFormModel* >(
399  reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelId())));
400  if( mpFormModel )
401  {
403  }
404  }
405  }
406 }
407 
409 {
410  if( mxDoc.Is() )
411  mxDoc->DoClose();
412 
413 }
414 
416 {
417  SvxGalleryDrawModel aModel;
418 
419  if( aModel.GetModel() )
420  {
421  if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) )
422  {
423  aURL = rURL;
424  bIsValid = CreateThumb( *aModel.GetModel() );
425  }
426  }
427 }
428 
430 {
431  Graphic aGraphic;
432  ImageMap aImageMap;
433  bool bRet = false;
434 
435  if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
436  {
437  bRet = SgaObject::CreateThumb( aGraphic );
438  }
439  else
440  {
441  const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0));
442 
443  if(pPage)
444  {
445  const tools::Rectangle aObjRect(pPage->GetAllObjBoundRect());
446 
447  if(aObjRect.GetWidth() && aObjRect.GetHeight())
448  {
450  FmFormView aView(const_cast< FmFormModel& >(rModel), pVDev);
451 
452  aView.ShowSdrPage(const_cast< FmFormPage* >(pPage));
453  aView.MarkAllObj();
454  aThumbBmp = aView.GetMarkedObjBitmapEx(true);
455  aGraphic = Graphic(aThumbBmp);
456  bRet = SgaObject::CreateThumb(aGraphic);
457  }
458  }
459  }
460 
461  return bRet;
462 }
463 
464 void SgaObjectSvDraw::WriteData( SvStream& rOut, const OUString& rDestDir ) const
465 {
466  SgaObject::WriteData( rOut, rDestDir );
467  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
468 }
469 
470 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
471 {
472  SgaObject::ReadData( rIn, rReadVersion );
473 
474  if( rReadVersion >= 5 )
475  aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
476 }
477 
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvStream & WriteBool(bool b)
long Width() const
virtual void ReadData(SvStream &rIn, sal_uInt16 &rReadVersion) override
Definition: galobj.cxx:340
virtual ~SgaObjectSound() override
Definition: galobj.cxx:304
URL aURL
virtual BitmapEx GetThumbBmp() const override
Definition: galobj.cxx:308
SvStream & WriteUInt16(sal_uInt16 nUInt16)
long FRound(double fVal)
bool CreateIMapGraphic(const FmFormModel &rModel, Graphic &rGraphic, ImageMap &rImageMap)
Definition: galmisc.cxx:119
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SvStream & ReadSgaObject(SvStream &rIn, SgaObject &rObj)
Definition: galobj.cxx:228
const tools::Rectangle & GetAllObjBoundRect() const
Definition: svdpage.cxx:688
virtual void WriteData(SvStream &rOut, const OUString &rDestDir) const override
Definition: galobj.cxx:333
bool CreateThumb(const FmFormModel &rModel)
Definition: galobj.cxx:429
sal_Int32 GetVersion() const
long Height() const
bool Is() const
virtual void WriteData(SvStream &rOut, const OUString &rDestDir) const override
Definition: galobj.cxx:464
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
SvStream & ReadCharAsBool(bool &rBool)
virtual SdrPageView * ShowSdrPage(SdrPage *pPage) override
Definition: fmview.cxx:293
SvStream & WriteSgaObject(SvStream &rOut, const SgaObject &rObj)
Definition: galobj.cxx:222
FmFormModel * GetModel() const
css::uno::Reference< css::frame::XModel > GetModel() const
FmFormModel * mpFormModel
SvStreamCompressFlags GetCompressMode() const
bool Convert(BmpConversion eConversion)
sal_uInt64 SeekRel(sal_Int64 nPos)
OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream &rStrm)
ErrCode GetError() const
BitmapEx GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked=false) const
Definition: svdxcgv.cxx:428
bool ReadDIBBitmapEx(BitmapEx &rTarget, SvStream &rIStm, bool bFileHeader, bool bMSOFormat)
SvStream & WriteGDIMetaFile(SvStream &rOStm, const GDIMetaFile &rGDIMetaFile)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
#define S_THUMB
Definition: galobj.hxx:30
virtual void ReadData(SvStream &rIn, sal_uInt16 &rReadVersion) override
Definition: galobj.cxx:470
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
void MarkAllObj(SdrPageView *pPV=nullptr)
Definition: svdmrkv.cxx:2361
bool IsEmpty() const
virtual void InsertPage(SdrPage *pPage, sal_uInt16 nPos=0xFFFF) override
Definition: fmmodel.cxx:79
bool WriteDIBBitmapEx(const BitmapEx &rSource, SvStream &rOStm)
OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream &rStrm, rtl_TextEncoding eEnc)
GalleryGraphicImportRet GalleryGraphicImport(const INetURLObject &rURL, Graphic &rGraphic, OUString &rFilterName)
Definition: galmisc.cxx:50
GraphicType GetType() const
sal_uInt32 COMPAT_FORMAT(char char1, char char2, char char3, char char4)
static SfxObjectShell * CreateObjectByFactoryName(const OUString &rURL, SfxObjectCreateMode=SfxObjectCreateMode::STANDARD)
virtual void ReadData(SvStream &rIn, sal_uInt16 &rReadVersion) override
Definition: galobj.cxx:273
const SdrPage * GetPage(sal_uInt16 nPgNum) const
Definition: svdmodel.cxx:1904
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStreamCompressFlags
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
void SetVersion(sal_Int32 n)
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream &rStrm, const OString &rStr)
GalSoundType eSoundType
Definition: galobj.hxx:94
void Init(const Graphic &rGraphic, const INetURLObject &rURL)
Definition: galobj.cxx:257
bool GallerySvDrawImport(SvStream &rIStm, SdrModel &rModel)
Definition: galmisc.cxx:75
GalSoundType
Definition: galobj.hxx:33
Size GetPrefSize() const
virtual void WriteData(SvStream &rOut, const OUString &rDestDir) const override
Definition: galobj.cxx:263
#define ERRCODE_NONE
static bool FileExists(const INetURLObject &rURL, const OUString &rExt)
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
bool DoInitNew(SfxMedium *pMedium=nullptr)
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: svdmodel.cxx:1997
SfxObjectShellLock mxDoc
sal_uInt16 GetVersion(sal_uInt16)
Definition: legacyitem.cxx:29
OUString sId
void SetCompressMode(SvStreamCompressFlags nNewMode)
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream &rStrm, const OUString &rStr, rtl_TextEncoding eEnc)
const Size & GetSizePixel() const
virtual SdrPage * AllocPage(bool bMasterPage) override
Definition: fmmodel.cxx:74