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