xref: /trunk/main/vcl/source/gdi/wall.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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