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 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 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 78 ImplWallpaper::~ImplWallpaper() 79 { 80 delete mpBitmap; 81 delete mpCache; 82 delete mpGradient; 83 delete mpRect; 84 } 85 86 // ----------------------------------------------------------------------- 87 88 void ImplWallpaper::ImplSetCachedBitmap( BitmapEx& rBmp ) 89 { 90 if( !mpCache ) 91 mpCache = new BitmapEx( rBmp ); 92 else 93 *mpCache = rBmp; 94 } 95 96 // ----------------------------------------------------------------------- 97 98 void ImplWallpaper::ImplReleaseCachedBitmap() 99 { 100 delete mpCache; 101 mpCache = NULL; 102 } 103 104 // ----------------------------------------------------------------------- 105 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 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 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 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 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 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 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 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 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 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 298 const Color& Wallpaper::GetColor() const 299 { 300 DBG_CHKTHIS( Wallpaper, NULL ); 301 302 return mpImplWallpaper->maColor; 303 } 304 305 // ----------------------------------------------------------------------- 306 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 323 WallpaperStyle Wallpaper::GetStyle() const 324 { 325 DBG_CHKTHIS( Wallpaper, NULL ); 326 327 return mpImplWallpaper->meStyle; 328 } 329 330 // ----------------------------------------------------------------------- 331 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 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 374 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 389 sal_Bool Wallpaper::IsBitmap() const 390 { 391 DBG_CHKTHIS( Wallpaper, NULL ); 392 393 return (mpImplWallpaper->mpBitmap != 0); 394 } 395 396 397 // ----------------------------------------------------------------------- 398 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 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 430 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 447 sal_Bool Wallpaper::IsGradient() const 448 { 449 DBG_CHKTHIS( Wallpaper, NULL ); 450 451 return (mpImplWallpaper->mpGradient != 0); 452 } 453 454 455 // ----------------------------------------------------------------------- 456 457 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 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 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 512 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 527 sal_Bool Wallpaper::IsRect() const 528 { 529 DBG_CHKTHIS( Wallpaper, NULL ); 530 531 return (mpImplWallpaper->mpRect != 0); 532 } 533 534 535 // ----------------------------------------------------------------------- 536 537 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 547 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 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 588 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 623 SvStream& operator>>( SvStream& rIStm, Wallpaper& rWallpaper ) 624 { 625 rWallpaper.ImplMakeUnique(); 626 return( rIStm >> *rWallpaper.mpImplWallpaper ); 627 } 628 629 // ----------------------------------------------------------------------- 630 631 SvStream& operator<<( SvStream& rOStm, const Wallpaper& rWallpaper ) 632 { 633 return( rOStm << *rWallpaper.mpImplWallpaper ); 634 } 635