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 658462 : ImplWallpaper::ImplWallpaper() :
32 658462 : maColor( COL_TRANSPARENT )
33 : {
34 658462 : mnRefCount = 1;
35 658462 : mpBitmap = NULL;
36 658462 : mpCache = NULL;
37 658462 : mpGradient = NULL;
38 658462 : mpRect = NULL;
39 658462 : meStyle = WALLPAPER_NULL;
40 658462 : }
41 :
42 1425 : ImplWallpaper::ImplWallpaper( const ImplWallpaper& rImplWallpaper ) :
43 1425 : maColor( rImplWallpaper.maColor )
44 : {
45 1425 : mnRefCount = 1;
46 1425 : meStyle = rImplWallpaper.meStyle;
47 :
48 1425 : if ( rImplWallpaper.mpBitmap )
49 0 : mpBitmap = new BitmapEx( *rImplWallpaper.mpBitmap );
50 : else
51 1425 : mpBitmap = NULL;
52 1425 : if( rImplWallpaper.mpCache )
53 0 : mpCache = new BitmapEx( *rImplWallpaper.mpCache );
54 : else
55 1425 : mpCache = NULL;
56 1425 : if ( rImplWallpaper.mpGradient )
57 0 : mpGradient = new Gradient( *rImplWallpaper.mpGradient );
58 : else
59 1425 : mpGradient = NULL;
60 1425 : if ( rImplWallpaper.mpRect )
61 0 : mpRect = new Rectangle( *rImplWallpaper.mpRect );
62 : else
63 1425 : mpRect = NULL;
64 1425 : }
65 :
66 652195 : ImplWallpaper::~ImplWallpaper()
67 : {
68 652195 : delete mpBitmap;
69 652195 : delete mpCache;
70 652195 : delete mpGradient;
71 652195 : delete mpRect;
72 652195 : }
73 :
74 2 : void ImplWallpaper::ImplSetCachedBitmap( BitmapEx& rBmp )
75 : {
76 2 : if( !mpCache )
77 1 : mpCache = new BitmapEx( rBmp );
78 : else
79 1 : *mpCache = rBmp;
80 2 : }
81 :
82 1426 : void ImplWallpaper::ImplReleaseCachedBitmap()
83 : {
84 1426 : delete mpCache;
85 1426 : mpCache = NULL;
86 1426 : }
87 :
88 0 : SvStream& ReadImplWallpaper( SvStream& rIStm, ImplWallpaper& rImplWallpaper )
89 : {
90 0 : VersionCompat aCompat( rIStm, StreamMode::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, StreamMode::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.WriteBool( bRect ).WriteBool( bGrad ).WriteBool( bBmp ).WriteBool( bDummy ).WriteBool( bDummy ).WriteBool( 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 2634 : inline void Wallpaper::ImplMakeUnique( bool bReleaseCache )
172 : {
173 : // copy them if other references exist
174 2634 : if ( mpImplWallpaper->mnRefCount != 1 )
175 : {
176 1425 : if ( mpImplWallpaper->mnRefCount )
177 218 : mpImplWallpaper->mnRefCount--;
178 1425 : mpImplWallpaper = new ImplWallpaper( *(mpImplWallpaper) );
179 : }
180 :
181 2634 : if( bReleaseCache )
182 1426 : mpImplWallpaper->ImplReleaseCachedBitmap();
183 2634 : }
184 :
185 568240 : Wallpaper::Wallpaper()
186 : {
187 :
188 568240 : static ImplWallpaper aStaticImplWallpaper;
189 :
190 568240 : aStaticImplWallpaper.mnRefCount = 0;
191 568240 : mpImplWallpaper = &aStaticImplWallpaper;
192 568240 : }
193 :
194 5976 : 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 5976 : mpImplWallpaper = rWallpaper.mpImplWallpaper;
200 : // RefCount == 0 for static objekts
201 5976 : if ( mpImplWallpaper->mnRefCount )
202 5927 : mpImplWallpaper->mnRefCount++;
203 5976 : }
204 :
205 658226 : Wallpaper::Wallpaper( const Color& rColor )
206 : {
207 :
208 658226 : mpImplWallpaper = new ImplWallpaper;
209 658226 : mpImplWallpaper->maColor = rColor;
210 658226 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
211 658226 : }
212 :
213 1 : Wallpaper::Wallpaper( const BitmapEx& rBmpEx )
214 : {
215 :
216 1 : mpImplWallpaper = new ImplWallpaper;
217 1 : mpImplWallpaper->mpBitmap = new BitmapEx( rBmpEx );
218 1 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
219 1 : }
220 :
221 20 : Wallpaper::Wallpaper( const Gradient& rGradient )
222 : {
223 :
224 20 : mpImplWallpaper = new ImplWallpaper;
225 20 : mpImplWallpaper->mpGradient = new Gradient( rGradient );
226 20 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
227 20 : }
228 :
229 1220346 : Wallpaper::~Wallpaper()
230 : {
231 : // if ImpData are not static then delete them if it is the last reference,
232 : // otherwise decrement reference counter
233 1220346 : if ( mpImplWallpaper->mnRefCount )
234 : {
235 998618 : if ( mpImplWallpaper->mnRefCount == 1 )
236 326011 : delete mpImplWallpaper;
237 : else
238 672607 : mpImplWallpaper->mnRefCount--;
239 : }
240 1220346 : }
241 :
242 219 : void Wallpaper::SetColor( const Color& rColor )
243 : {
244 :
245 219 : ImplMakeUnique();
246 219 : mpImplWallpaper->maColor = rColor;
247 :
248 219 : if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
249 0 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
250 219 : }
251 :
252 426718 : const Color& Wallpaper::GetColor() const
253 : {
254 :
255 426718 : return mpImplWallpaper->maColor;
256 : }
257 :
258 1208 : void Wallpaper::SetStyle( WallpaperStyle eStyle )
259 : {
260 :
261 1208 : ImplMakeUnique( false );
262 :
263 1208 : if( eStyle == WALLPAPER_APPLICATIONGRADIENT )
264 : // set a dummy gradient, the correct gradient
265 : // will be created dynamically in GetGradient()
266 1207 : SetGradient( ImplGetApplicationGradient() );
267 :
268 1208 : mpImplWallpaper->meStyle = eStyle;
269 1208 : }
270 :
271 736809 : WallpaperStyle Wallpaper::GetStyle() const
272 : {
273 :
274 736809 : 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 1 : BitmapEx Wallpaper::GetBitmap() const
303 : {
304 :
305 1 : if ( mpImplWallpaper->mpBitmap )
306 1 : return *(mpImplWallpaper->mpBitmap);
307 : else
308 : {
309 0 : BitmapEx aBmp;
310 0 : return aBmp;
311 : }
312 : }
313 :
314 367954 : bool Wallpaper::IsBitmap() const
315 : {
316 :
317 367954 : return (mpImplWallpaper->mpBitmap != 0);
318 : }
319 :
320 1207 : void Wallpaper::SetGradient( const Gradient& rGradient )
321 : {
322 :
323 1207 : ImplMakeUnique();
324 :
325 1207 : if ( mpImplWallpaper->mpGradient )
326 0 : *(mpImplWallpaper->mpGradient) = rGradient;
327 : else
328 1207 : mpImplWallpaper->mpGradient = new Gradient( rGradient );
329 :
330 1207 : if( WALLPAPER_NULL == mpImplWallpaper->meStyle || WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
331 1207 : mpImplWallpaper->meStyle = WALLPAPER_TILE;
332 1207 : }
333 :
334 1227 : Gradient Wallpaper::GetGradient() const
335 : {
336 :
337 1227 : if( WALLPAPER_APPLICATIONGRADIENT == mpImplWallpaper->meStyle )
338 1207 : return ImplGetApplicationGradient();
339 20 : else if ( mpImplWallpaper->mpGradient )
340 20 : return *(mpImplWallpaper->mpGradient);
341 : else
342 : {
343 0 : Gradient aGradient;
344 0 : return aGradient;
345 : }
346 : }
347 :
348 754062 : bool Wallpaper::IsGradient() const
349 : {
350 :
351 754062 : return (mpImplWallpaper->mpGradient != 0);
352 : }
353 :
354 2414 : Gradient Wallpaper::ImplGetApplicationGradient() const
355 : {
356 2414 : Gradient g;
357 2414 : g.SetAngle( 900 );
358 2414 : g.SetStyle( GradientStyle_LINEAR );
359 2414 : g.SetStartColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
360 : // no 'extreme' gradient when high contrast
361 2414 : if( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
362 0 : g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
363 : else
364 2414 : g.SetEndColor( Application::GetSettings().GetStyleSettings().GetFaceGradientColor() );
365 2414 : 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 0 : bool Wallpaper::IsScrollable() const
417 : {
418 0 : if ( mpImplWallpaper->meStyle == WALLPAPER_NULL )
419 0 : return false;
420 0 : else if ( !mpImplWallpaper->mpBitmap && !mpImplWallpaper->mpGradient )
421 0 : return true;
422 0 : else if ( mpImplWallpaper->mpBitmap )
423 0 : return (mpImplWallpaper->meStyle == WALLPAPER_TILE);
424 : else
425 0 : return false;
426 : }
427 :
428 793533 : 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 793533 : if ( rWallpaper.mpImplWallpaper->mnRefCount )
434 686244 : 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 793533 : if ( mpImplWallpaper->mnRefCount )
439 : {
440 345294 : if ( mpImplWallpaper->mnRefCount == 1 )
441 325969 : delete mpImplWallpaper;
442 : else
443 19325 : mpImplWallpaper->mnRefCount--;
444 : }
445 :
446 793533 : mpImplWallpaper = rWallpaper.mpImplWallpaper;
447 :
448 793533 : return *this;
449 : }
450 :
451 7 : bool Wallpaper::operator==( const Wallpaper& rWallpaper ) const
452 : {
453 :
454 7 : if ( mpImplWallpaper == rWallpaper.mpImplWallpaper )
455 0 : return true;
456 :
457 14 : if ( ( mpImplWallpaper->meStyle != rWallpaper.mpImplWallpaper->meStyle ) ||
458 7 : ( mpImplWallpaper->maColor != rWallpaper.mpImplWallpaper->maColor ) )
459 0 : return false;
460 :
461 14 : if ( mpImplWallpaper->mpRect != rWallpaper.mpImplWallpaper->mpRect
462 7 : && ( !mpImplWallpaper->mpRect
463 0 : || !rWallpaper.mpImplWallpaper->mpRect
464 0 : || *(mpImplWallpaper->mpRect) != *(rWallpaper.mpImplWallpaper->mpRect) ) )
465 0 : return false;
466 :
467 14 : if ( mpImplWallpaper->mpBitmap != rWallpaper.mpImplWallpaper->mpBitmap
468 7 : && ( !mpImplWallpaper->mpBitmap
469 0 : || !rWallpaper.mpImplWallpaper->mpBitmap
470 0 : || *(mpImplWallpaper->mpBitmap) != *(rWallpaper.mpImplWallpaper->mpBitmap) ) )
471 0 : return false;
472 :
473 14 : if ( mpImplWallpaper->mpGradient != rWallpaper.mpImplWallpaper->mpGradient
474 7 : && ( !mpImplWallpaper->mpGradient
475 0 : || !rWallpaper.mpImplWallpaper->mpGradient
476 0 : || *(mpImplWallpaper->mpGradient) != *(rWallpaper.mpImplWallpaper->mpGradient) ) )
477 0 : return false;
478 :
479 7 : 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 : }
492 :
493 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|