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