xref: /trunk/main/svx/source/gallery2/galobj.cxx (revision 5fdc4257b5e43545f8f7841d9e8303d3a99b1714)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #define ENABLE_BYTESTRING_STREAM_OPERATORS
28 
29 #include <com/sun/star/lang/XUnoTunnel.hpp>
30 #include <sfx2/objsh.hxx>
31 #include <sfx2/docfac.hxx>
32 
33 #include <comphelper/classids.hxx>
34 #include <unotools/pathoptions.hxx>
35 
36 #include <tools/rcid.h>
37 #include <tools/vcompat.hxx>
38 #include <vcl/virdev.hxx>
39 #include <svl/itempool.hxx>
40 #include <svx/fmmodel.hxx>
41 #include <svx/fmview.hxx>
42 #include <svx/fmpage.hxx>
43 #include "gallery.hrc"
44 #include "svx/galmisc.hxx"
45 #include "galobj.hxx"
46 #include <vcl/salbtype.hxx>     // FRound
47 #include <vcl/svapp.hxx>
48 
49 #include "gallerydrawmodel.hxx"
50 
51 using namespace ::com::sun::star;
52 
53 // -------------
54 // - SgaObject -
55 // -------------
56 
57 SgaObject::SgaObject() :
58         bIsValid    ( sal_False ),
59         bIsThumbBmp ( sal_True )
60 {
61 }
62 
63 // ------------------------------------------------------------------------
64 
65 sal_Bool SgaObject::CreateThumb( const Graphic& rGraphic )
66 {
67     sal_Bool bRet = sal_False;
68 
69     if( rGraphic.GetType() == GRAPHIC_BITMAP )
70     {
71         BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
72         Size        aBmpSize( aBmpEx.GetSizePixel() );
73 
74         if( aBmpSize.Width() && aBmpSize.Height() )
75         {
76             const Color aWhite( COL_WHITE );
77 
78             if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL &&
79                 aBmpEx.GetPrefSize().Width() > 0 &&
80                 aBmpEx.GetPrefSize().Height() > 0 )
81             {
82                 Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) );
83 
84                 if( aLogSize.Width() > 0 && aLogSize.Height() > 0 )
85                 {
86                     double  fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
87                     double  fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
88 
89                     if( fFactorPix > fFactorLog )
90                         aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog );
91                     else
92                         aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog );
93 
94                     aBmpEx.SetSizePixel( aBmpSize, BMP_SCALE_BESTQUALITY );
95                 }
96             }
97 
98             aThumbBmp = aBmpEx.GetBitmap( &aWhite );
99 
100             if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
101             {
102                 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
103                 bRet = sal_True;
104             }
105             else
106             {
107                 const float fFactor  = (float) aBmpSize.Width() / aBmpSize.Height();
108                 const Size  aNewSize( Max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
109                                       Max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
110 
111                 if(aThumbBmp.Scale(
112                     (double) aNewSize.Width() / aBmpSize.Width(),
113                     (double) aNewSize.Height() / aBmpSize.Height(),
114                     BMP_SCALE_BESTQUALITY ) )
115                 {
116                     aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
117                     bRet = sal_True;
118                 }
119             }
120         }
121     }
122     else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
123     {
124         const Size aPrefSize( rGraphic.GetPrefSize() );
125         const double fFactor  = (double)aPrefSize.Width() / (double)aPrefSize.Height();
126         Size aSize( S_THUMB, S_THUMB );
127         if ( fFactor < 1.0 )
128             aSize.Width() = (sal_Int32)( S_THUMB * fFactor );
129         else
130             aSize.Height() = (sal_Int32)( S_THUMB / fFactor );
131 
132         const GraphicConversionParameters aParameters(aSize, false, true, true, true);
133         aThumbBmp = rGraphic.GetBitmap(aParameters);
134 
135         if( !aThumbBmp.IsEmpty() )
136         {
137             aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
138             bRet = sal_True;
139         }
140     }
141 
142     return bRet;
143 }
144 
145 // ------------------------------------------------------------------------
146 
147 void SgaObject::WriteData( SvStream& rOut, const String& rDestDir ) const
148 {
149     static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
150 
151     rOut << nInventor << (sal_uInt16) 0x0004 << GetVersion() << (sal_uInt16) GetObjKind();
152     rOut << bIsThumbBmp;
153 
154     if( bIsThumbBmp )
155     {
156         const sal_uInt16    nOldCompressMode = rOut.GetCompressMode();
157         const sal_uIntPtr       nOldVersion = rOut.GetVersion();
158 
159         rOut.SetCompressMode( COMPRESSMODE_ZBITMAP );
160         rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
161 
162         rOut << aThumbBmp;
163 
164         rOut.SetVersion( nOldVersion );
165         rOut.SetCompressMode( nOldCompressMode );
166     }
167     else
168         rOut << aThumbMtf;
169 
170     String aURLWithoutDestDir = String(aURL.GetMainURL( INetURLObject::NO_DECODE ));
171     aURLWithoutDestDir.SearchAndReplace(rDestDir, String());
172     rOut << ByteString( aURLWithoutDestDir, RTL_TEXTENCODING_UTF8 );
173 }
174 
175 // ------------------------------------------------------------------------
176 
177 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
178 {
179     ByteString  aTmpStr;
180     sal_uInt32      nTmp32;
181     sal_uInt16      nTmp16;
182 
183     rIn >> nTmp32 >> nTmp16 >> rReadVersion >> nTmp16 >> bIsThumbBmp;
184 
185     if( bIsThumbBmp )
186         rIn >> aThumbBmp;
187     else
188         rIn >> aThumbMtf;
189 
190     rIn >> aTmpStr; aURL = INetURLObject( String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
191 }
192 
193 // ------------------------------------------------------------------------
194 
195 const String SgaObject::GetTitle() const
196 {
197     String aReturnValue( aTitle );
198     if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
199     {
200         if ( aReturnValue.GetTokenCount( ':' ) == 3 )
201         {
202             String      aPrivateInd  ( aReturnValue.GetToken( 0, ':' ) );
203             String      aResourceName( aReturnValue.GetToken( 1, ':' ) );
204             sal_Int32   nResId       ( aReturnValue.GetToken( 2, ':' ).ToInt32() );
205             if ( aReturnValue.GetToken( 0, ':' ).EqualsAscii( "private" ) &&
206                 aResourceName.Len() && ( nResId > 0 ) && ( nResId < 0x10000 ) )
207             {
208                 ByteString aMgrName( aResourceName, RTL_TEXTENCODING_UTF8 );
209                 ResMgr* pResMgr = ResMgr::CreateResMgr( aMgrName.GetBuffer(),
210                             Application::GetSettings().GetUILocale() );
211                 if ( pResMgr )
212                 {
213                     ResId aResId( (sal_uInt16)nResId, *pResMgr );
214                     aResId.SetRT( RSC_STRING );
215                     if ( pResMgr->IsAvailable( aResId ) )
216                     {
217                         aReturnValue = String( aResId );
218                     }
219                     delete pResMgr;
220                 }
221             }
222         }
223     }
224     return aReturnValue;
225 }
226 
227 // ------------------------------------------------------------------------
228 
229 void SgaObject::SetTitle( const String& rTitle )
230 {
231     aTitle = rTitle;
232 }
233 
234 // ------------------------------------------------------------------------
235 
236 SvStream& operator<<( SvStream& rOut, const SgaObject& rObj )
237 {
238     rObj.WriteData( rOut, String() );
239     return rOut;
240 }
241 
242 // ------------------------------------------------------------------------
243 
244 SvStream& operator>>( SvStream& rIn, SgaObject& rObj )
245 {
246     sal_uInt16 nReadVersion;
247 
248     rObj.ReadData( rIn, nReadVersion );
249     rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
250 
251     return rIn;
252 }
253 
254 // ----------------
255 // - SgaObjectBmp -
256 // ----------------
257 
258 SgaObjectBmp::SgaObjectBmp()
259 {
260 }
261 
262 // ------------------------------------------------------------------------
263 
264 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
265 {
266     Graphic aGraphic;
267     String  aFilter;
268 
269     if ( SGA_IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
270         Init( aGraphic, rURL );
271 }
272 
273 // ------------------------------------------------------------------------
274 
275 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const String& )
276 {
277     if( FileExists( rURL ) )
278         Init( rGraphic, rURL );
279 }
280 
281 // ------------------------------------------------------------------------
282 
283 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
284 {
285     aURL = rURL;
286     bIsValid = CreateThumb( rGraphic );
287 }
288 
289 // ------------------------------------------------------------------------
290 
291 void SgaObjectBmp::WriteData( SvStream& rOut, const String& rDestDir ) const
292 {
293     String  aDummyStr;
294     char    aDummy[ 10 ];
295 
296     // Version setzen
297     SgaObject::WriteData( rOut, rDestDir );
298     rOut.Write( aDummy, 10 );
299     rOut << ByteString( aDummyStr, RTL_TEXTENCODING_UTF8 ) << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
300 }
301 
302 // ------------------------------------------------------------------------
303 
304 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
305 {
306     ByteString aTmpStr;
307 
308     SgaObject::ReadData( rIn, rReadVersion );
309     rIn.SeekRel( 10 ); // 16, 16, 32, 16
310     rIn >> aTmpStr; // dummy
311 
312     if( rReadVersion >= 5 )
313     {
314         rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
315     }
316 }
317 
318 // ------------------
319 // - SgaObjectSound -
320 // ------------------
321 DBG_NAME(SgaObjectSound)
322 
323 SgaObjectSound::SgaObjectSound() :
324     eSoundType( SOUND_STANDARD )
325 {
326     DBG_CTOR(SgaObjectSound,NULL);
327 
328 }
329 
330 // ------------------------------------------------------------------------
331 
332 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
333     eSoundType( SOUND_STANDARD )
334 {
335     DBG_CTOR(SgaObjectSound,NULL);
336 
337     if( FileExists( rURL ) )
338     {
339         aURL = rURL;
340         aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
341         bIsValid = sal_True;
342     }
343     else
344         bIsValid = sal_False;
345 }
346 
347 // ------------------------------------------------------------------------
348 
349 SgaObjectSound::~SgaObjectSound()
350 {
351 
352     DBG_DTOR(SgaObjectSound,NULL);
353 }
354 
355 // ------------------------------------------------------------------------
356 
357 Bitmap SgaObjectSound::GetThumbBmp() const
358 {
359     sal_uInt16 nId;
360 
361     switch( eSoundType )
362     {
363         case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break;
364         case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break;
365         case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break;
366         case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break;
367         case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break;
368         case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break;
369         case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break;
370 
371         // standard
372         default:
373              nId = RID_SVXBMP_GALLERY_MEDIA;
374         break;
375     }
376 
377     const BitmapEx  aBmpEx( GAL_RESID( nId ) );
378     const Color     aTransColor( COL_WHITE );
379 
380     return aBmpEx.GetBitmap( &aTransColor );
381 }
382 
383 // ------------------------------------------------------------------------
384 
385 void SgaObjectSound::WriteData( SvStream& rOut, const String& rDestDir ) const
386 {
387     SgaObject::WriteData( rOut, rDestDir );
388     rOut << (sal_uInt16) eSoundType << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
389 }
390 
391 // ------------------------------------------------------------------------
392 
393 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
394 {
395     SgaObject::ReadData( rIn, rReadVersion );
396 
397     if( rReadVersion >= 5 )
398     {
399         ByteString  aTmpStr;
400         sal_uInt16      nTmp16;
401 
402         rIn >> nTmp16; eSoundType = (GalSoundType) nTmp16;
403 
404         if( rReadVersion >= 6 )
405         {
406             rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
407         }
408     }
409 }
410 
411 // -----------------
412 // - SgaObjectAnim -
413 // -----------------
414 
415 SgaObjectAnim::SgaObjectAnim()
416 {
417 }
418 
419 // ------------------------------------------------------------------------
420 
421 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
422                               const INetURLObject& rURL,
423                               const String& )
424 {
425     aURL = rURL;
426     bIsValid = CreateThumb( rGraphic );
427 }
428 
429 // -----------------
430 // - SgaObjectINet -
431 // -----------------
432 
433 SgaObjectINet::SgaObjectINet()
434 {
435 }
436 
437 // ------------------------------------------------------------------------
438 
439 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const String& rFormatName ) :
440             SgaObjectAnim   ( rGraphic, rURL, rFormatName )
441 {
442 }
443 
444 // -------------------
445 // - SgaObjectSvDraw -
446 // -------------------
447 
448 SgaObjectSvDraw::SgaObjectSvDraw()
449 {
450 }
451 
452 // ------------------------------------------------------------------------
453 
454 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
455 {
456     aURL = rURL;
457     bIsValid = CreateThumb( rModel );
458 }
459 
460 // ------------------------------------------------------------------------
461 DBG_NAME(SvxGalleryDrawModel)
462 
463 SvxGalleryDrawModel::SvxGalleryDrawModel()
464 : mpFormModel( 0 )
465 {
466     DBG_CTOR(SvxGalleryDrawModel,NULL);
467 
468     const String sFactoryURL(RTL_CONSTASCII_USTRINGPARAM("sdraw"));
469 
470     mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
471 
472     if( mxDoc.Is() )
473     {
474         mxDoc->DoInitNew(0);
475 
476         uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
477         if( xTunnel.is() )
478         {
479             mpFormModel = dynamic_cast< FmFormModel* >(
480                 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId())));
481             if( mpFormModel )
482             {
483                 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
484             }
485         }
486     }
487 }
488 
489 // ------------------------------------------------------------------------
490 
491 SvxGalleryDrawModel::~SvxGalleryDrawModel()
492 {
493     if( mxDoc.Is() )
494         mxDoc->DoClose();
495 
496     DBG_DTOR(SvxGalleryDrawModel,NULL);
497 }
498 
499 // ------------------------------------------------------------------------
500 
501 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
502 {
503     SvxGalleryDrawModel aModel;
504 
505     if( aModel.GetModel() )
506     {
507         if( GallerySvDrawImport( rIStm, *aModel.GetModel()  ) )
508         {
509             aURL = rURL;
510             bIsValid = CreateThumb( *aModel.GetModel()  );
511         }
512     }
513 }
514 
515 // ------------------------------------------------------------------------
516 
517 sal_Bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
518 {
519     Graphic     aGraphic;
520     ImageMap    aImageMap;
521     sal_Bool        bRet = sal_False;
522 
523     if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
524         bRet = SgaObject::CreateThumb( aGraphic );
525     else
526     {
527         VirtualDevice aVDev;
528 
529         aVDev.SetOutputSizePixel( Size( S_THUMB*2, S_THUMB*2 ) );
530 
531         bRet = DrawCentered( &aVDev, rModel );
532         if( bRet )
533         {
534             aThumbBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
535 
536             Size aMS( 2, 2 );
537             BmpFilterParam aParam( aMS );
538             aThumbBmp.Filter( BMP_FILTER_MOSAIC, &aParam );
539             aThumbBmp.Scale( Size( S_THUMB, S_THUMB ) );
540 
541             aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
542         }
543     }
544 
545     return bRet;
546 }
547 
548 // ------------------------------------------------------------------------
549 
550 sal_Bool SgaObjectSvDraw::DrawCentered( OutputDevice* pOut, const FmFormModel& rModel )
551 {
552     const FmFormPage*   pPage = static_cast< const FmFormPage* >( rModel.GetPage( 0 ) );
553     sal_Bool                bRet = sal_False;
554 
555     if( pOut && pPage )
556     {
557         const Rectangle aObjRect( pPage->GetAllObjBoundRect() );
558         const Size      aOutSizePix( pOut->GetOutputSizePixel() );
559 
560         if( aObjRect.GetWidth() && aObjRect.GetHeight() && aOutSizePix.Width() > 2 && aOutSizePix.Height() > 2 )
561         {
562             FmFormView      aView( const_cast< FmFormModel* >( &rModel ), pOut );
563             MapMode         aMap( rModel.GetScaleUnit() );
564             Rectangle       aDrawRectPix( Point( 1, 1 ), Size( aOutSizePix.Width() - 2, aOutSizePix.Height() - 2 ) );
565             const double    fFactor  = (double) aObjRect.GetWidth() / aObjRect.GetHeight();
566             Fraction        aFrac( FRound( fFactor < 1. ? aDrawRectPix.GetWidth() * fFactor : aDrawRectPix.GetWidth() ),
567                                    pOut->LogicToPixel( aObjRect.GetSize(), aMap ).Width() );
568 
569             aMap.SetScaleX( aFrac );
570             aMap.SetScaleY( aFrac );
571 
572             const Size aDrawSize( pOut->PixelToLogic( aDrawRectPix.GetSize(), aMap ) );
573             Point aOrigin( pOut->PixelToLogic( aDrawRectPix.TopLeft(), aMap ) );
574 
575             aOrigin.X() += ( ( aDrawSize.Width() - aObjRect.GetWidth() ) >> 1 ) - aObjRect.Left();
576             aOrigin.Y() += ( ( aDrawSize.Height() - aObjRect.GetHeight() ) >> 1 ) - aObjRect.Top();
577             aMap.SetOrigin( aOrigin );
578 
579             aView.SetPageVisible( sal_False );
580             aView.SetBordVisible( sal_False );
581             aView.SetGridVisible( sal_False );
582             aView.SetHlplVisible( sal_False );
583             aView.SetGlueVisible( sal_False );
584 
585             pOut->Push();
586             pOut->SetMapMode( aMap );
587             aView.ShowSdrPage( const_cast< FmFormPage* >( pPage ));
588             aView.CompleteRedraw( pOut, Rectangle( pOut->PixelToLogic( Point() ), pOut->GetOutputSize() ) );
589             pOut->Pop();
590 
591             bRet = sal_True;
592         }
593     }
594 
595     return bRet;
596 }
597 
598 // ------------------------------------------------------------------------
599 
600 void SgaObjectSvDraw::WriteData( SvStream& rOut, const String& rDestDir ) const
601 {
602     SgaObject::WriteData( rOut, rDestDir );
603     rOut << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
604 }
605 
606 // ------------------------------------------------------------------------
607 
608 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
609 {
610     SgaObject::ReadData( rIn, rReadVersion );
611 
612     if( rReadVersion >= 5 )
613     {
614         ByteString aTmpStr;
615         rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
616     }
617 }
618