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