xref: /aoo41x/main/vcl/source/gdi/wall.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/stream.hxx>
32 #include <tools/vcompat.hxx>
33 #include <tools/debug.hxx>
34 
35 #include <vcl/bitmapex.hxx>
36 #include <vcl/gradient.hxx>
37 #include <vcl/wall.hxx>
38 #include <vcl/svapp.hxx>
39 
40 #include <wall2.hxx>
41 
42 
43 DBG_NAME( Wallpaper )
44 
45 // -----------------------------------------------------------------------
46 
47 ImplWallpaper::ImplWallpaper() :
48 	maColor( COL_TRANSPARENT )
49 {
50 	mnRefCount		= 1;
51 	mpBitmap		= NULL;
52 	mpCache			= NULL;
53 	mpGradient		= NULL;
54 	mpRect			= NULL;
55 	meStyle 		= WALLPAPER_NULL;
56 }
57 
58 // -----------------------------------------------------------------------
59 
60 ImplWallpaper::ImplWallpaper( const ImplWallpaper& rImplWallpaper ) :
61 	maColor( rImplWallpaper.maColor )
62 {
63 	mnRefCount = 1;
64 	meStyle = rImplWallpaper.meStyle;
65 
66 	if ( rImplWallpaper.mpBitmap )
67 		mpBitmap = new BitmapEx( *rImplWallpaper.mpBitmap );
68 	else
69 		mpBitmap = NULL;
70 	if( rImplWallpaper.mpCache )
71 		mpCache = new BitmapEx( *rImplWallpaper.mpCache );
72 	else
73 		mpCache = NULL;
74 	if ( rImplWallpaper.mpGradient )
75 		mpGradient = new Gradient( *rImplWallpaper.mpGradient );
76 	else
77 		mpGradient = NULL;
78 	if ( rImplWallpaper.mpRect )
79 		mpRect = new Rectangle( *rImplWallpaper.mpRect );
80 	else
81 		mpRect = NULL;
82 }
83 
84 // -----------------------------------------------------------------------
85 
86 ImplWallpaper::~ImplWallpaper()
87 {
88 	delete mpBitmap;
89 	delete mpCache;
90 	delete mpGradient;
91 	delete mpRect;
92 }
93 
94 // -----------------------------------------------------------------------
95 
96 void ImplWallpaper::ImplSetCachedBitmap( BitmapEx& rBmp )
97 {
98 	if( !mpCache )
99 		mpCache = new BitmapEx( rBmp );
100 	else
101 		*mpCache = rBmp;
102 }
103 
104 // -----------------------------------------------------------------------
105 
106 void ImplWallpaper::ImplReleaseCachedBitmap()
107 {
108 	delete mpCache;
109 	mpCache = NULL;
110 }
111 
112 // -----------------------------------------------------------------------
113 
114 SvStream& operator>>( SvStream& rIStm, ImplWallpaper& rImplWallpaper )
115 {
116 	VersionCompat	aCompat( rIStm, STREAM_READ );
117 	sal_uInt16			nTmp16;
118 
119 	delete rImplWallpaper.mpRect;
120 	rImplWallpaper.mpRect = NULL;
121 
122 	delete rImplWallpaper.mpGradient;
123 	rImplWallpaper.mpGradient = NULL;
124 
125 	delete rImplWallpaper.mpBitmap;
126 	rImplWallpaper.mpBitmap = NULL;
127 
128 	// version 1
129 	rIStm >> rImplWallpaper.maColor;
130 	rIStm >> nTmp16; rImplWallpaper.meStyle = (WallpaperStyle) nTmp16;
131 
132 	// version 2
133 	if( aCompat.GetVersion() >= 2 )
134 	{
135 		sal_Bool bRect, bGrad, bBmp, bDummy;
136 
137 		rIStm >> bRect >> bGrad >> bBmp >> bDummy >> bDummy >> bDummy;
138 
139 		if( bRect )
140 		{
141 			rImplWallpaper.mpRect = new Rectangle;
142 			rIStm >> *rImplWallpaper.mpRect;
143 		}
144 
145 		if( bGrad )
146 		{
147 			rImplWallpaper.mpGradient = new Gradient;
148 			rIStm >> *rImplWallpaper.mpGradient;
149 		}
150 
151 		if( bBmp )
152 		{
153 			rImplWallpaper.mpBitmap = new BitmapEx;
154 			rIStm >> *rImplWallpaper.mpBitmap;
155 		}
156 
157 		// version 3 (new color format)
158 		if( aCompat.GetVersion() >= 3 )
159 		{
160 			rImplWallpaper.maColor.Read( rIStm, sal_True );
161 		}
162 	}
163 
164 	return rIStm;
165 }
166 
167 // -----------------------------------------------------------------------
168 
169 SvStream& operator<<( SvStream& rOStm, const ImplWallpaper& rImplWallpaper )
170 {
171 	VersionCompat	aCompat( rOStm, STREAM_WRITE, 3 );
172 	sal_Bool			bRect = ( rImplWallpaper.mpRect != NULL );
173 	sal_Bool			bGrad = ( rImplWallpaper.mpGradient != NULL );
174 	sal_Bool			bBmp = ( rImplWallpaper.mpBitmap != NULL );
175 	sal_Bool			bDummy = sal_False;
176 
177 	// version 1
178 	rOStm << rImplWallpaper.maColor << (sal_uInt16) rImplWallpaper.meStyle;
179 
180 	// version 2
181 	rOStm << bRect << bGrad << bBmp << bDummy << bDummy << bDummy;
182 
183 	if( bRect )
184 		rOStm << *rImplWallpaper.mpRect;
185 
186 	if( bGrad )
187 		rOStm << *rImplWallpaper.mpGradient;
188 
189 	if( bBmp )
190 		rOStm << *rImplWallpaper.mpBitmap;
191 
192 	// version 3 (new color format)
193 	( (Color&) rImplWallpaper.maColor ).Write( rOStm, sal_True );
194 
195 	return rOStm;
196 }
197 
198 // -----------------------------------------------------------------------
199 
200 inline void Wallpaper::ImplMakeUnique( sal_Bool bReleaseCache )
201 {
202 	// Falls noch andere Referenzen bestehen, dann kopieren
203 	if ( mpImplWallpaper->mnRefCount != 1 )
204 	{
205 		if ( mpImplWallpaper->mnRefCount )
206 			mpImplWallpaper->mnRefCount--;
207 		mpImplWallpaper = new ImplWallpaper( *(mpImplWallpaper) );
208 	}
209 
210 	if( bReleaseCache )
211 		mpImplWallpaper->ImplReleaseCachedBitmap();
212 }
213 
214 // -----------------------------------------------------------------------
215 
216 Wallpaper::Wallpaper()
217 {
218 	DBG_CTOR( Wallpaper, NULL );
219 
220 	static ImplWallpaper aStaticImplWallpaper;
221 
222 	aStaticImplWallpaper.mnRefCount = 0;
223 	mpImplWallpaper = &aStaticImplWallpaper;
224 }
225 
226 // -----------------------------------------------------------------------
227 
228 Wallpaper::Wallpaper( const Wallpaper& rWallpaper )
229 {
230 	DBG_CTOR( Wallpaper, NULL );
231 	DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
232 	DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFFFFFE, "Wallpaper: RefCount overflow" );
233 
234 	// Instance Daten uebernehmen und Referenzcounter erhoehen
235 	mpImplWallpaper = rWallpaper.mpImplWallpaper;
236 	// RefCount == 0 fuer statische Objekte
237 	if ( mpImplWallpaper->mnRefCount )
238 		mpImplWallpaper->mnRefCount++;
239 }
240 
241 // -----------------------------------------------------------------------
242 
243 Wallpaper::Wallpaper( const Color& rColor )
244 {
245 	DBG_CTOR( Wallpaper, NULL );
246 
247 	mpImplWallpaper 			= new ImplWallpaper;
248 	mpImplWallpaper->maColor	= rColor;
249 	mpImplWallpaper->meStyle	= WALLPAPER_TILE;
250 }
251 
252 // -----------------------------------------------------------------------
253 
254 Wallpaper::Wallpaper( const BitmapEx& rBmpEx )
255 {
256 	DBG_CTOR( Wallpaper, NULL );
257 
258 	mpImplWallpaper 			= new ImplWallpaper;
259 	mpImplWallpaper->mpBitmap	= new BitmapEx( rBmpEx );
260 	mpImplWallpaper->meStyle	= WALLPAPER_TILE;
261 }
262 
263 // -----------------------------------------------------------------------
264 
265 Wallpaper::Wallpaper( const Gradient& rGradient )
266 {
267 	DBG_CTOR( Wallpaper, NULL );
268 
269 	mpImplWallpaper 			= new ImplWallpaper;
270 	mpImplWallpaper->mpGradient = new Gradient( rGradient );
271 	mpImplWallpaper->meStyle	= WALLPAPER_TILE;
272 }
273 
274 // -----------------------------------------------------------------------
275 
276 Wallpaper::~Wallpaper()
277 {
278 	DBG_DTOR( Wallpaper, NULL );
279 
280 	// Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
281 	// die letzte Referenz ist, sonst Referenzcounter decrementieren
282 	if ( mpImplWallpaper->mnRefCount )
283 	{
284 		if ( mpImplWallpaper->mnRefCount == 1 )
285 			delete mpImplWallpaper;
286 		else
287 			mpImplWallpaper->mnRefCount--;
288 	}
289 }
290 
291 // -----------------------------------------------------------------------
292 
293 void Wallpaper::SetColor( const Color& rColor )
294 {
295 	DBG_CHKTHIS( Wallpaper, NULL );
296 
297 	ImplMakeUnique();
298 	mpImplWallpaper->maColor = rColor;
299 
300 	if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
301 		mpImplWallpaper->meStyle = WALLPAPER_TILE;
302 }
303 
304 // -----------------------------------------------------------------------
305 
306 const Color& Wallpaper::GetColor() const
307 {
308 	DBG_CHKTHIS( Wallpaper, NULL );
309 
310     return mpImplWallpaper->maColor;
311 }
312 
313 // -----------------------------------------------------------------------
314 
315 void Wallpaper::SetStyle( WallpaperStyle eStyle )
316 {
317 	DBG_CHKTHIS( Wallpaper, NULL );
318 
319 	ImplMakeUnique( sal_False );
320 
321     if( eStyle == WALLPAPER_APPLICATIONGRADIENT )
322         // set a dummy gradient, the correct gradient
323         // will be created dynamically in GetGradient()
324         SetGradient( ImplGetApplicationGradient() );
325 
326 	mpImplWallpaper->meStyle = eStyle;
327 }
328 
329 // -----------------------------------------------------------------------
330 
331 WallpaperStyle Wallpaper::GetStyle() const
332 {
333 	DBG_CHKTHIS( Wallpaper, NULL );
334 
335     return mpImplWallpaper->meStyle;
336 }
337 
338 // -----------------------------------------------------------------------
339 
340 void Wallpaper::SetBitmap( const BitmapEx& rBitmap )
341 {
342 	DBG_CHKTHIS( Wallpaper, NULL );
343 
344 	if ( !rBitmap )
345 	{
346 		if ( mpImplWallpaper->mpBitmap )
347 		{
348 			ImplMakeUnique();
349 			delete mpImplWallpaper->mpBitmap;
350 			mpImplWallpaper->mpBitmap = NULL;
351 		}
352 	}
353 	else
354 	{
355 		ImplMakeUnique();
356 		if ( mpImplWallpaper->mpBitmap )
357 			*(mpImplWallpaper->mpBitmap) = rBitmap;
358 		else
359 			mpImplWallpaper->mpBitmap = new BitmapEx( rBitmap );
360 	}
361 
362 	if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle)
363 		mpImplWallpaper->meStyle = WALLPAPER_TILE;
364 }
365 
366 // -----------------------------------------------------------------------
367 
368 void Wallpaper::SetBitmap()
369 {
370 	DBG_CHKTHIS( Wallpaper, NULL );
371 
372 	if ( mpImplWallpaper->mpBitmap )
373 	{
374 		ImplMakeUnique();
375 		delete mpImplWallpaper->mpBitmap;
376 		mpImplWallpaper->mpBitmap = NULL;
377 	}
378 }
379 
380 // -----------------------------------------------------------------------
381 
382 BitmapEx Wallpaper::GetBitmap() const
383 {
384 	DBG_CHKTHIS( Wallpaper, NULL );
385 
386 	if ( mpImplWallpaper->mpBitmap )
387 		return *(mpImplWallpaper->mpBitmap);
388 	else
389 	{
390 		BitmapEx aBmp;
391 		return aBmp;
392 	}
393 }
394 
395 // -----------------------------------------------------------------------
396 
397 sal_Bool Wallpaper::IsBitmap() const
398 {
399 	DBG_CHKTHIS( Wallpaper, NULL );
400 
401     return (mpImplWallpaper->mpBitmap != 0);
402 }
403 
404 
405 // -----------------------------------------------------------------------
406 
407 void Wallpaper::SetGradient( const Gradient& rGradient )
408 {
409 	DBG_CHKTHIS( Wallpaper, NULL );
410 
411 	ImplMakeUnique();
412 
413 	if ( mpImplWallpaper->mpGradient )
414 		*(mpImplWallpaper->mpGradient) = rGradient;
415 	else
416 		mpImplWallpaper->mpGradient = new Gradient( rGradient );
417 
418 	if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
419 		mpImplWallpaper->meStyle = WALLPAPER_TILE;
420 }
421 
422 // -----------------------------------------------------------------------
423 
424 void Wallpaper::SetGradient()
425 {
426 	DBG_CHKTHIS( Wallpaper, NULL );
427 
428 	if ( mpImplWallpaper->mpGradient )
429 	{
430 		ImplMakeUnique();
431 		delete mpImplWallpaper->mpGradient;
432 		mpImplWallpaper->mpGradient = NULL;
433 	}
434 }
435 
436 // -----------------------------------------------------------------------
437 
438 Gradient Wallpaper::GetGradient() const
439 {
440 	DBG_CHKTHIS( Wallpaper, NULL );
441 
442     if( WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
443         return ImplGetApplicationGradient();
444 	else if ( mpImplWallpaper->mpGradient )
445 		return *(mpImplWallpaper->mpGradient);
446 	else
447 	{
448 		Gradient aGradient;
449 		return aGradient;
450 	}
451 }
452 
453 // -----------------------------------------------------------------------
454 
455 sal_Bool Wallpaper::IsGradient() const
456 {
457 	DBG_CHKTHIS( Wallpaper, NULL );
458 
459     return (mpImplWallpaper->mpGradient != 0);
460 }
461 
462 
463 // -----------------------------------------------------------------------
464 
465 Gradient Wallpaper::ImplGetApplicationGradient() const
466 {
467     Gradient g;
468     g.SetAngle( 900 );
469     g.SetStyle( GRADIENT_LINEAR );
470     g.SetStartColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
471     // no 'extreme' gradient when high contrast
472 	if( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
473 		g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
474 	else
475 		g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceGradientColor() );
476     return g;
477 }
478 
479 // -----------------------------------------------------------------------
480 
481 void Wallpaper::SetRect( const Rectangle& rRect )
482 {
483 	DBG_CHKTHIS( Wallpaper, NULL );
484 
485 	ImplMakeUnique( sal_False );
486 
487 	if ( rRect.IsEmpty() )
488 	{
489 		if ( mpImplWallpaper->mpRect )
490 		{
491 			delete mpImplWallpaper->mpRect;
492 			mpImplWallpaper->mpRect = NULL;
493 		}
494 	}
495 	else
496 	{
497 		if ( mpImplWallpaper->mpRect )
498 			*(mpImplWallpaper->mpRect) = rRect;
499 		else
500 			mpImplWallpaper->mpRect = new Rectangle( rRect );
501 	}
502 }
503 
504 // -----------------------------------------------------------------------
505 
506 void Wallpaper::SetRect()
507 {
508 	DBG_CHKTHIS( Wallpaper, NULL );
509 
510 	if ( mpImplWallpaper->mpRect )
511 	{
512 		ImplMakeUnique( sal_False );
513 		delete mpImplWallpaper->mpRect;
514 		mpImplWallpaper->mpRect = NULL;
515 	}
516 }
517 
518 // -----------------------------------------------------------------------
519 
520 Rectangle Wallpaper::GetRect() const
521 {
522 	DBG_CHKTHIS( Wallpaper, NULL );
523 
524 	if ( mpImplWallpaper->mpRect )
525 		return *(mpImplWallpaper->mpRect);
526 	else
527 	{
528 		Rectangle aRect;
529 		return aRect;
530 	}
531 }
532 
533 // -----------------------------------------------------------------------
534 
535 sal_Bool Wallpaper::IsRect() const
536 {
537 	DBG_CHKTHIS( Wallpaper, NULL );
538 
539     return (mpImplWallpaper->mpRect != 0);
540 }
541 
542 
543 // -----------------------------------------------------------------------
544 
545 sal_Bool Wallpaper::IsFixed() const
546 {
547 	if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
548 		return sal_False;
549 	else
550 		return (!mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient);
551 }
552 
553 // -----------------------------------------------------------------------
554 
555 sal_Bool Wallpaper::IsScrollable() const
556 {
557 	if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
558 		return sal_False;
559 	else if ( !mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient )
560 		return sal_True;
561 	else if ( mpImplWallpaper->mpBitmap )
562 		return (mpImplWallpaper->meStyle == WALLPAPER_TILE);
563 	else
564 		return sal_False;
565 }
566 
567 // -----------------------------------------------------------------------
568 
569 Wallpaper& Wallpaper::operator=( const Wallpaper& rWallpaper )
570 {
571 	DBG_CHKTHIS( Wallpaper, NULL );
572 	DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
573 	DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFFFFFE, "Wallpaper: RefCount overflow" );
574 
575 	// Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
576 	if ( rWallpaper.mpImplWallpaper->mnRefCount )
577 		rWallpaper.mpImplWallpaper->mnRefCount++;
578 
579 	// Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
580 	// die letzte Referenz ist, sonst Referenzcounter decrementieren
581 	if ( mpImplWallpaper->mnRefCount )
582 	{
583 		if ( mpImplWallpaper->mnRefCount == 1 )
584 			delete mpImplWallpaper;
585 		else
586 			mpImplWallpaper->mnRefCount--;
587 	}
588 
589 	mpImplWallpaper = rWallpaper.mpImplWallpaper;
590 
591 	return *this;
592 }
593 
594 // -----------------------------------------------------------------------
595 
596 sal_Bool Wallpaper::operator==( const Wallpaper& rWallpaper ) const
597 {
598 	DBG_CHKTHIS( Wallpaper, NULL );
599 	DBG_CHKOBJ( &rWallpaper, Wallpaper, NULL );
600 
601 	if ( mpImplWallpaper == rWallpaper.mpImplWallpaper )
602 		return sal_True;
603 
604 	if ( ( mpImplWallpaper->meStyle != rWallpaper.mpImplWallpaper->meStyle ) ||
605 	     ( mpImplWallpaper->maColor	!= rWallpaper.mpImplWallpaper->maColor ) )
606 		return sal_False;
607 
608 	if ( mpImplWallpaper->mpRect != rWallpaper.mpImplWallpaper->mpRect
609 	     && ( !mpImplWallpaper->mpRect
610 		      || !rWallpaper.mpImplWallpaper->mpRect
611 			  || *(mpImplWallpaper->mpRect) != *(rWallpaper.mpImplWallpaper->mpRect) ) )
612 		return sal_False;
613 
614 	if ( mpImplWallpaper->mpBitmap != rWallpaper.mpImplWallpaper->mpBitmap
615 	     && ( !mpImplWallpaper->mpBitmap
616 		      || !rWallpaper.mpImplWallpaper->mpBitmap
617 			  || *(mpImplWallpaper->mpBitmap) != *(rWallpaper.mpImplWallpaper->mpBitmap) ) )
618 		return sal_False;
619 
620 	if ( mpImplWallpaper->mpGradient != rWallpaper.mpImplWallpaper->mpGradient
621 	     && ( !mpImplWallpaper->mpGradient
622 		      || !rWallpaper.mpImplWallpaper->mpGradient
623 			  || *(mpImplWallpaper->mpGradient) != *(rWallpaper.mpImplWallpaper->mpGradient) ) )
624 		return sal_False;
625 
626 	return sal_True;
627 }
628 
629 // -----------------------------------------------------------------------
630 
631 SvStream& operator>>( SvStream& rIStm, Wallpaper& rWallpaper )
632 {
633 	rWallpaper.ImplMakeUnique();
634 	return( rIStm >> *rWallpaper.mpImplWallpaper );
635 }
636 
637 // -----------------------------------------------------------------------
638 
639 SvStream& operator<<( SvStream& rOStm, const Wallpaper& rWallpaper )
640 {
641 	return( rOStm << *rWallpaper.mpImplWallpaper );
642 }
643