Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/stream.hxx>
21 : #include <tools/vcompat.hxx>
22 : #include <tools/debug.hxx>
23 : #include <vcl/bitmapex.hxx>
24 : #include <vcl/gradient.hxx>
25 : #include <vcl/wall.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <wall2.hxx>
28 : #include <vcl/dibtools.hxx>
29 : #include <vcl/settings.hxx>
30 :
31 1014331 : ImplWallpaper::ImplWallpaper() :
32 1014331 : maColor( COL_TRANSPARENT )
33 : {
34 1014331 : mnRefCount = 1;
35 1014331 : mpBitmap = NULL;
36 1014331 : mpCache = NULL;
37 1014331 : mpGradient = NULL;
38 1014331 : mpRect = NULL;
39 1014331 : meStyle = WALLPAPER_NULL;
40 1014331 : }
41 :
42 151369 : ImplWallpaper::ImplWallpaper( const ImplWallpaper& rImplWallpaper ) :
43 151369 : maColor( rImplWallpaper.maColor )
44 : {
45 151369 : mnRefCount = 1;
46 151369 : meStyle = rImplWallpaper.meStyle;
47 :
48 151369 : if ( rImplWallpaper.mpBitmap )
49 0 : mpBitmap = new BitmapEx( *rImplWallpaper.mpBitmap );
50 : else
51 151369 : mpBitmap = NULL;
52 151369 : if( rImplWallpaper.mpCache )
53 0 : mpCache = new BitmapEx( *rImplWallpaper.mpCache );
54 : else
55 151369 : mpCache = NULL;
56 151369 : if ( rImplWallpaper.mpGradient )
57 0 : mpGradient = new Gradient( *rImplWallpaper.mpGradient );
58 : else
59 151369 : mpGradient = NULL;
60 151369 : if ( rImplWallpaper.mpRect )
61 0 : mpRect = new Rectangle( *rImplWallpaper.mpRect );
62 : else
63 151369 : mpRect = NULL;
64 151369 : }
65 :
66 1164974 : ImplWallpaper::~ImplWallpaper()
67 : {
68 1164974 : delete mpBitmap;
69 1164974 : delete mpCache;
70 1164974 : delete mpGradient;
71 1164974 : delete mpRect;
72 1164974 : }
73 :
74 2 : void ImplWallpaper::ImplSetCachedBitmap( BitmapEx& rBmp )
75 : {
76 2 : if( !mpCache )
77 2 : mpCache = new BitmapEx( rBmp );
78 : else
79 0 : *mpCache = rBmp;
80 2 : }
81 :
82 151371 : void ImplWallpaper::ImplReleaseCachedBitmap()
83 : {
84 151371 : delete mpCache;
85 151371 : mpCache = NULL;
86 151371 : }
87 :
88 0 : SvStream& ReadImplWallpaper( SvStream& rIStm, ImplWallpaper& rImplWallpaper )
89 : {
90 0 : VersionCompat aCompat( rIStm, STREAM_READ );
91 : sal_uInt16 nTmp16;
92 :
93 0 : delete rImplWallpaper.mpRect;
94 0 : rImplWallpaper.mpRect = NULL;
95 :
96 0 : delete rImplWallpaper.mpGradient;
97 0 : rImplWallpaper.mpGradient = NULL;
98 :
99 0 : delete rImplWallpaper.mpBitmap;
100 0 : rImplWallpaper.mpBitmap = NULL;
101 :
102 : // version 1
103 0 : ReadColor( rIStm, rImplWallpaper.maColor );
104 0 : rIStm.ReadUInt16( nTmp16 ); rImplWallpaper.meStyle = (WallpaperStyle) nTmp16;
105 :
106 : // version 2
107 0 : if( aCompat.GetVersion() >= 2 )
108 : {
109 : bool bRect, bGrad, bBmp, bDummy;
110 :
111 0 : rIStm.ReadCharAsBool( bRect ).ReadCharAsBool( bGrad ).ReadCharAsBool( bBmp ).ReadCharAsBool( bDummy ).ReadCharAsBool( bDummy ).ReadCharAsBool( bDummy );
112 :
113 0 : if( bRect )
114 : {
115 0 : rImplWallpaper.mpRect = new Rectangle;
116 0 : ReadRectangle( rIStm, *rImplWallpaper.mpRect );
117 : }
118 :
119 0 : if( bGrad )
120 : {
121 0 : rImplWallpaper.mpGradient = new Gradient;
122 0 : ReadGradient( rIStm, *rImplWallpaper.mpGradient );
123 : }
124 :
125 0 : if( bBmp )
126 : {
127 0 : rImplWallpaper.mpBitmap = new BitmapEx;
128 0 : ReadDIBBitmapEx(*rImplWallpaper.mpBitmap, rIStm);
129 : }
130 :
131 : // version 3 (new color format)
132 0 : if( aCompat.GetVersion() >= 3 )
133 : {
134 0 : rImplWallpaper.maColor.Read( rIStm, true );
135 : }
136 : }
137 :
138 0 : return rIStm;
139 : }
140 :
141 0 : SvStream& WriteImplWallpaper( SvStream& rOStm, const ImplWallpaper& rImplWallpaper )
142 : {
143 0 : VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
144 0 : bool bRect = ( rImplWallpaper.mpRect != NULL );
145 0 : bool bGrad = ( rImplWallpaper.mpGradient != NULL );
146 0 : bool bBmp = ( rImplWallpaper.mpBitmap != NULL );
147 0 : bool bDummy = false;
148 :
149 : // version 1
150 0 : WriteColor( rOStm, rImplWallpaper.maColor );
151 0 : rOStm.WriteUInt16( rImplWallpaper.meStyle );
152 :
153 : // version 2
154 0 : rOStm.WriteUChar( bRect ).WriteUChar( bGrad ).WriteUChar( bBmp ).WriteUChar( bDummy ).WriteUChar( bDummy ).WriteUChar( bDummy );
155 :
156 0 : if( bRect )
157 0 : WriteRectangle( rOStm, *rImplWallpaper.mpRect );
158 :
159 0 : if( bGrad )
160 0 : WriteGradient( rOStm, *rImplWallpaper.mpGradient );
161 :
162 0 : if( bBmp )
163 0 : WriteDIBBitmapEx(*rImplWallpaper.mpBitmap, rOStm);
164 :
165 : // version 3 (new color format)
166 0 : ( (Color&) rImplWallpaper.maColor ).Write( rOStm, true );
167 :
168 0 : return rOStm;
169 : }
170 :
171 302589 : inline void Wallpaper::ImplMakeUnique( bool bReleaseCache )
172 : {
173 : // copy them if other references exist
174 302589 : if ( mpImplWallpaper->mnRefCount != 1 )
175 : {
176 151369 : if ( mpImplWallpaper->mnRefCount )
177 153 : mpImplWallpaper->mnRefCount--;
178 151369 : mpImplWallpaper = new ImplWallpaper( *(mpImplWallpaper) );
179 : }
180 :
181 302589 : if( bReleaseCache )
182 151371 : mpImplWallpaper->ImplReleaseCachedBitmap();
183 302589 : }
184 :
185 1021045 : Wallpaper::Wallpaper()
186 : {
187 :
188 1021045 : static ImplWallpaper aStaticImplWallpaper;
189 :
190 1021045 : aStaticImplWallpaper.mnRefCount = 0;
191 1021045 : mpImplWallpaper = &aStaticImplWallpaper;
192 1021045 : }
193 :
194 8421 : Wallpaper::Wallpaper( const Wallpaper& rWallpaper )
195 : {
196 : DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFFFFFE, "Wallpaper: RefCount overflow" );
197 :
198 : // use Instance data and increment reference counter
199 8421 : mpImplWallpaper = rWallpaper.mpImplWallpaper;
200 : // RefCount == 0 for static objekts
201 8421 : if ( mpImplWallpaper->mnRefCount )
202 8408 : mpImplWallpaper->mnRefCount++;
203 8421 : }
204 :
205 1007061 : Wallpaper::Wallpaper( const Color& rColor )
206 : {
207 :
208 1007061 : mpImplWallpaper = new ImplWallpaper;
209 1007061 : mpImplWallpaper->maColor = rColor;
210 1007061 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
211 1007061 : }
212 :
213 2 : Wallpaper::Wallpaper( const BitmapEx& rBmpEx )
214 : {
215 :
216 2 : mpImplWallpaper = new ImplWallpaper;
217 2 : mpImplWallpaper->mpBitmap = new BitmapEx( rBmpEx );
218 2 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
219 2 : }
220 :
221 6950 : Wallpaper::Wallpaper( const Gradient& rGradient )
222 : {
223 :
224 6950 : mpImplWallpaper = new ImplWallpaper;
225 6950 : mpImplWallpaper->mpGradient = new Gradient( rGradient );
226 6950 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
227 6950 : }
228 :
229 2042646 : Wallpaper::~Wallpaper()
230 : {
231 : // if ImpData are not static then delete them if it is the last reference,
232 : // otherwise decrement reference counter
233 2042646 : if ( mpImplWallpaper->mnRefCount )
234 : {
235 1660604 : if ( mpImplWallpaper->mnRefCount == 1 )
236 464818 : delete mpImplWallpaper;
237 : else
238 1195786 : mpImplWallpaper->mnRefCount--;
239 : }
240 2042646 : }
241 :
242 155 : void Wallpaper::SetColor( const Color& rColor )
243 : {
244 :
245 155 : ImplMakeUnique();
246 155 : mpImplWallpaper->maColor = rColor;
247 :
248 155 : if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
249 0 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
250 155 : }
251 :
252 675864 : const Color& Wallpaper::GetColor() const
253 : {
254 :
255 675864 : return mpImplWallpaper->maColor;
256 : }
257 :
258 151218 : void Wallpaper::SetStyle( WallpaperStyle eStyle )
259 : {
260 :
261 151218 : ImplMakeUnique( false );
262 :
263 151218 : if( eStyle == WALLPAPER_APPLICATIONGRADIENT )
264 : // set a dummy gradient, the correct gradient
265 : // will be created dynamically in GetGradient()
266 151216 : SetGradient( ImplGetApplicationGradient() );
267 :
268 151218 : mpImplWallpaper->meStyle = eStyle;
269 151218 : }
270 :
271 1426320 : WallpaperStyle Wallpaper::GetStyle() const
272 : {
273 :
274 1426320 : return mpImplWallpaper->meStyle;
275 : }
276 :
277 0 : void Wallpaper::SetBitmap( const BitmapEx& rBitmap )
278 : {
279 :
280 0 : if ( !rBitmap )
281 : {
282 0 : if ( mpImplWallpaper->mpBitmap )
283 : {
284 0 : ImplMakeUnique();
285 0 : delete mpImplWallpaper->mpBitmap;
286 0 : mpImplWallpaper->mpBitmap = NULL;
287 : }
288 : }
289 : else
290 : {
291 0 : ImplMakeUnique();
292 0 : if ( mpImplWallpaper->mpBitmap )
293 0 : *(mpImplWallpaper->mpBitmap) = rBitmap;
294 : else
295 0 : mpImplWallpaper->mpBitmap = new BitmapEx( rBitmap );
296 : }
297 :
298 0 : if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle)
299 0 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
300 0 : }
301 :
302 2 : BitmapEx Wallpaper::GetBitmap() const
303 : {
304 :
305 2 : if ( mpImplWallpaper->mpBitmap )
306 2 : return *(mpImplWallpaper->mpBitmap);
307 : else
308 : {
309 0 : BitmapEx aBmp;
310 0 : return aBmp;
311 : }
312 : }
313 :
314 580182 : bool Wallpaper::IsBitmap() const
315 : {
316 :
317 580182 : return (mpImplWallpaper->mpBitmap != 0);
318 : }
319 :
320 151216 : void Wallpaper::SetGradient( const Gradient& rGradient )
321 : {
322 :
323 151216 : ImplMakeUnique();
324 :
325 151216 : if ( mpImplWallpaper->mpGradient )
326 0 : *(mpImplWallpaper->mpGradient) = rGradient;
327 : else
328 151216 : mpImplWallpaper->mpGradient = new Gradient( rGradient );
329 :
330 151216 : if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
331 151216 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
332 151216 : }
333 :
334 17391 : Gradient Wallpaper::GetGradient() const
335 : {
336 :
337 17391 : if( WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
338 13685 : return ImplGetApplicationGradient();
339 3706 : else if ( mpImplWallpaper->mpGradient )
340 3706 : return *(mpImplWallpaper->mpGradient);
341 : else
342 : {
343 0 : Gradient aGradient;
344 0 : return aGradient;
345 : }
346 : }
347 :
348 1316583 : bool Wallpaper::IsGradient() const
349 : {
350 :
351 1316583 : return (mpImplWallpaper->mpGradient != 0);
352 : }
353 :
354 164901 : Gradient Wallpaper::ImplGetApplicationGradient() const
355 : {
356 164901 : Gradient g;
357 164901 : g.SetAngle( 900 );
358 164901 : g.SetStyle( GradientStyle_LINEAR );
359 164901 : g.SetStartColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
360 : // no 'extreme' gradient when high contrast
361 164901 : if( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
362 0 : g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
363 : else
364 164901 : g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceGradientColor() );
365 164901 : return g;
366 : }
367 :
368 0 : void Wallpaper::SetRect( const Rectangle& rRect )
369 : {
370 :
371 0 : ImplMakeUnique( false );
372 :
373 0 : if ( rRect.IsEmpty() )
374 : {
375 0 : if ( mpImplWallpaper->mpRect )
376 : {
377 0 : delete mpImplWallpaper->mpRect;
378 0 : mpImplWallpaper->mpRect = NULL;
379 : }
380 : }
381 : else
382 : {
383 0 : if ( mpImplWallpaper->mpRect )
384 0 : *(mpImplWallpaper->mpRect) = rRect;
385 : else
386 0 : mpImplWallpaper->mpRect = new Rectangle( rRect );
387 : }
388 0 : }
389 :
390 0 : Rectangle Wallpaper::GetRect() const
391 : {
392 :
393 0 : if ( mpImplWallpaper->mpRect )
394 0 : return *(mpImplWallpaper->mpRect);
395 : else
396 : {
397 0 : Rectangle aRect;
398 0 : return aRect;
399 : }
400 : }
401 :
402 2 : bool Wallpaper::IsRect() const
403 : {
404 :
405 2 : return (mpImplWallpaper->mpRect != 0);
406 : }
407 :
408 0 : bool Wallpaper::IsFixed() const
409 : {
410 0 : if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
411 0 : return false;
412 : else
413 0 : return (!mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient);
414 : }
415 :
416 144 : bool Wallpaper::IsScrollable() const
417 : {
418 144 : if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
419 0 : return false;
420 144 : else if ( !mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient )
421 144 : return true;
422 0 : else if ( mpImplWallpaper->mpBitmap )
423 0 : return (mpImplWallpaper->meStyle == WALLPAPER_TILE);
424 : else
425 0 : return false;
426 : }
427 :
428 1372735 : Wallpaper& Wallpaper::operator=( const Wallpaper& rWallpaper )
429 : {
430 : DBG_ASSERT( rWallpaper.mpImplWallpaper->mnRefCount < 0xFFFFFFFE, "Wallpaper: RefCount overflow" );
431 :
432 : // first increment reference counter, in order to self assign
433 1372735 : if ( rWallpaper.mpImplWallpaper->mnRefCount )
434 1205020 : rWallpaper.mpImplWallpaper->mnRefCount++;
435 :
436 : // if ImpData are not static then delete them if it is the last reference,
437 : // otherwise decrement reference counter
438 1372735 : if ( mpImplWallpaper->mnRefCount )
439 : {
440 717313 : if ( mpImplWallpaper->mnRefCount == 1 )
441 699838 : delete mpImplWallpaper;
442 : else
443 17475 : mpImplWallpaper->mnRefCount--;
444 : }
445 :
446 1372735 : mpImplWallpaper = rWallpaper.mpImplWallpaper;
447 :
448 1372735 : return *this;
449 : }
450 :
451 16 : bool Wallpaper::operator==( const Wallpaper& rWallpaper ) const
452 : {
453 :
454 16 : if ( mpImplWallpaper == rWallpaper.mpImplWallpaper )
455 0 : return true;
456 :
457 32 : if ( ( mpImplWallpaper->meStyle != rWallpaper.mpImplWallpaper->meStyle ) ||
458 16 : ( mpImplWallpaper->maColor != rWallpaper.mpImplWallpaper->maColor ) )
459 0 : return false;
460 :
461 32 : if ( mpImplWallpaper->mpRect != rWallpaper.mpImplWallpaper->mpRect
462 16 : && ( !mpImplWallpaper->mpRect
463 0 : || !rWallpaper.mpImplWallpaper->mpRect
464 0 : || *(mpImplWallpaper->mpRect) != *(rWallpaper.mpImplWallpaper->mpRect) ) )
465 0 : return false;
466 :
467 32 : if ( mpImplWallpaper->mpBitmap != rWallpaper.mpImplWallpaper->mpBitmap
468 16 : && ( !mpImplWallpaper->mpBitmap
469 0 : || !rWallpaper.mpImplWallpaper->mpBitmap
470 0 : || *(mpImplWallpaper->mpBitmap) != *(rWallpaper.mpImplWallpaper->mpBitmap) ) )
471 0 : return false;
472 :
473 32 : if ( mpImplWallpaper->mpGradient != rWallpaper.mpImplWallpaper->mpGradient
474 16 : && ( !mpImplWallpaper->mpGradient
475 0 : || !rWallpaper.mpImplWallpaper->mpGradient
476 0 : || *(mpImplWallpaper->mpGradient) != *(rWallpaper.mpImplWallpaper->mpGradient) ) )
477 0 : return false;
478 :
479 16 : return true;
480 : }
481 :
482 0 : SvStream& ReadWallpaper( SvStream& rIStm, Wallpaper& rWallpaper )
483 : {
484 0 : rWallpaper.ImplMakeUnique();
485 0 : return ReadImplWallpaper( rIStm, *rWallpaper.mpImplWallpaper );
486 : }
487 :
488 0 : SvStream& WriteWallpaper( SvStream& rOStm, const Wallpaper& rWallpaper )
489 : {
490 0 : return WriteImplWallpaper( rOStm, *rWallpaper.mpImplWallpaper );
491 1233 : }
492 :
493 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|