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