xref: /trunk/main/svx/source/gallery2/galobj.cxx (revision 54628ca4)
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