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