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