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