Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tools/stream.hxx>
30 : : #include <tools/vcompat.hxx>
31 : : #include <tools/debug.hxx>
32 : : #include <vcl/gradient.hxx>
33 : :
34 : : // =======================================================================
35 : :
36 : : DBG_NAME( Gradient )
37 : :
38 : : // -----------------------------------------------------------------------
39 : :
40 : 150961 : Impl_Gradient::Impl_Gradient() :
41 : : maStartColor( COL_BLACK ),
42 : 150961 : maEndColor( COL_WHITE )
43 : : {
44 : 150961 : mnRefCount = 1;
45 : 150961 : meStyle = GradientStyle_LINEAR;
46 : 150961 : mnAngle = 0;
47 : 150961 : mnBorder = 0;
48 : 150961 : mnOfsX = 50;
49 : 150961 : mnOfsY = 50;
50 : 150961 : mnIntensityStart = 100;
51 : 150961 : mnIntensityEnd = 100;
52 : 150961 : mnStepCount = 0;
53 : 150961 : }
54 : :
55 : : // -----------------------------------------------------------------------
56 : :
57 : 113828 : Impl_Gradient::Impl_Gradient( const Impl_Gradient& rImplGradient ) :
58 : : maStartColor( rImplGradient.maStartColor ),
59 : 113828 : maEndColor( rImplGradient.maEndColor )
60 : : {
61 : 113828 : mnRefCount = 1;
62 : 113828 : meStyle = rImplGradient.meStyle;
63 : 113828 : mnAngle = rImplGradient.mnAngle;
64 : 113828 : mnBorder = rImplGradient.mnBorder;
65 : 113828 : mnOfsX = rImplGradient.mnOfsX;
66 : 113828 : mnOfsY = rImplGradient.mnOfsY;
67 : 113828 : mnIntensityStart = rImplGradient.mnIntensityStart;
68 : 113828 : mnIntensityEnd = rImplGradient.mnIntensityEnd;
69 : 113828 : mnStepCount = rImplGradient.mnStepCount;
70 : 113828 : }
71 : :
72 : : // -----------------------------------------------------------------------
73 : :
74 : 714312 : void Gradient::MakeUnique()
75 : : {
76 : : // Falls noch andere Referenzen bestehen, dann kopieren
77 [ + + ]: 714312 : if ( mpImplGradient->mnRefCount != 1 )
78 : : {
79 [ + - ]: 113828 : if( mpImplGradient->mnRefCount )
80 : 113828 : mpImplGradient->mnRefCount--;
81 : :
82 : 113828 : mpImplGradient = new Impl_Gradient( *mpImplGradient );
83 : : }
84 : 714312 : }
85 : :
86 : : // -----------------------------------------------------------------------
87 : :
88 : 150121 : Gradient::Gradient()
89 : : {
90 : : DBG_CTOR( Gradient, NULL );
91 : :
92 : 150121 : mpImplGradient = new Impl_Gradient;
93 : 150121 : }
94 : :
95 : : // -----------------------------------------------------------------------
96 : :
97 : 277482 : Gradient::Gradient( const Gradient& rGradient )
98 : : {
99 : : DBG_CTOR( Gradient, NULL );
100 : : DBG_CHKOBJ( &rGradient, Gradient, NULL );
101 : :
102 : : // Instance Daten uebernehmen und Referenzcounter erhoehen
103 : 277482 : mpImplGradient = rGradient.mpImplGradient;
104 : 277482 : mpImplGradient->mnRefCount++;
105 : 277482 : }
106 : :
107 : : // -----------------------------------------------------------------------
108 : :
109 : 840 : Gradient::Gradient( GradientStyle eStyle,
110 : : const Color& rStartColor, const Color& rEndColor )
111 : : {
112 : : DBG_CTOR( Gradient, NULL );
113 : :
114 : 840 : mpImplGradient = new Impl_Gradient;
115 : 840 : mpImplGradient->meStyle = eStyle;
116 : 840 : mpImplGradient->maStartColor = rStartColor;
117 : 840 : mpImplGradient->maEndColor = rEndColor;
118 : 840 : }
119 : :
120 : : // -----------------------------------------------------------------------
121 : :
122 : 426930 : Gradient::~Gradient()
123 : : {
124 : : DBG_DTOR( Gradient, NULL );
125 : :
126 : : // Wenn es die letzte Referenz ist, loeschen,
127 : : // sonst Referenzcounter decrementieren
128 [ + + ]: 426930 : if ( mpImplGradient->mnRefCount == 1 )
129 : 263276 : delete mpImplGradient;
130 : : else
131 : 163654 : mpImplGradient->mnRefCount--;
132 : 426930 : }
133 : :
134 : : // -----------------------------------------------------------------------
135 : :
136 : 150121 : void Gradient::SetStyle( GradientStyle eStyle )
137 : : {
138 : : DBG_CHKTHIS( Gradient, NULL );
139 : :
140 : 150121 : MakeUnique();
141 : 150121 : mpImplGradient->meStyle = eStyle;
142 : 150121 : }
143 : :
144 : : // -----------------------------------------------------------------------
145 : :
146 : 150121 : void Gradient::SetStartColor( const Color& rColor )
147 : : {
148 : : DBG_CHKTHIS( Gradient, NULL );
149 : :
150 : 150121 : MakeUnique();
151 : 150121 : mpImplGradient->maStartColor = rColor;
152 : 150121 : }
153 : :
154 : : // -----------------------------------------------------------------------
155 : :
156 : 150121 : void Gradient::SetEndColor( const Color& rColor )
157 : : {
158 : : DBG_CHKTHIS( Gradient, NULL );
159 : :
160 : 150121 : MakeUnique();
161 : 150121 : mpImplGradient->maEndColor = rColor;
162 : 150121 : }
163 : :
164 : : // -----------------------------------------------------------------------
165 : :
166 : 150121 : void Gradient::SetAngle( sal_uInt16 nAngle )
167 : : {
168 : : DBG_CHKTHIS( Gradient, NULL );
169 : :
170 : 150121 : MakeUnique();
171 : 150121 : mpImplGradient->mnAngle = nAngle;
172 : 150121 : }
173 : :
174 : : // -----------------------------------------------------------------------
175 : :
176 : 0 : void Gradient::SetBorder( sal_uInt16 nBorder )
177 : : {
178 : : DBG_CHKTHIS( Gradient, NULL );
179 : :
180 : 0 : MakeUnique();
181 : 0 : mpImplGradient->mnBorder = nBorder;
182 : 0 : }
183 : :
184 : : // -----------------------------------------------------------------------
185 : :
186 : 0 : void Gradient::SetOfsX( sal_uInt16 nOfsX )
187 : : {
188 : : DBG_CHKTHIS( Gradient, NULL );
189 : :
190 : 0 : MakeUnique();
191 : 0 : mpImplGradient->mnOfsX = nOfsX;
192 : 0 : }
193 : :
194 : : // -----------------------------------------------------------------------
195 : :
196 : 0 : void Gradient::SetOfsY( sal_uInt16 nOfsY )
197 : : {
198 : : DBG_CHKTHIS( Gradient, NULL );
199 : :
200 : 0 : MakeUnique();
201 : 0 : mpImplGradient->mnOfsY = nOfsY;
202 : 0 : }
203 : :
204 : : // -----------------------------------------------------------------------
205 : :
206 : 0 : void Gradient::SetStartIntensity( sal_uInt16 nIntens )
207 : : {
208 : : DBG_CHKTHIS( Gradient, NULL );
209 : :
210 : 0 : MakeUnique();
211 : 0 : mpImplGradient->mnIntensityStart = nIntens;
212 : 0 : }
213 : :
214 : : // -----------------------------------------------------------------------
215 : :
216 : 0 : void Gradient::SetEndIntensity( sal_uInt16 nIntens )
217 : : {
218 : : DBG_CHKTHIS( Gradient, NULL );
219 : :
220 : 0 : MakeUnique();
221 : 0 : mpImplGradient->mnIntensityEnd = nIntens;
222 : 0 : }
223 : :
224 : : // -----------------------------------------------------------------------
225 : :
226 : 113828 : void Gradient::SetSteps( sal_uInt16 nSteps )
227 : : {
228 : : DBG_CHKTHIS( Gradient, NULL );
229 : :
230 : 113828 : MakeUnique();
231 : 113828 : mpImplGradient->mnStepCount = nSteps;
232 : 113828 : }
233 : :
234 : : // -----------------------------------------------------------------------
235 : :
236 : 113828 : void Gradient::GetBoundRect( const Rectangle& rRect, Rectangle& rBoundRect, Point& rCenter ) const
237 : : {
238 : 113828 : Rectangle aRect( rRect );
239 : 113828 : sal_uInt16 nAngle = GetAngle() % 3600;
240 : :
241 [ # # ][ + - ]: 113828 : if( GetStyle() == GradientStyle_LINEAR || GetStyle() == GradientStyle_AXIAL )
[ - + ]
242 : : {
243 : 113828 : aRect.Left()--;
244 : 113828 : aRect.Top()--;
245 : 113828 : aRect.Right()++;
246 : 113828 : aRect.Bottom()++;
247 : :
248 : 113828 : const double fAngle = nAngle * F_PI1800;
249 [ + - ]: 113828 : const double fWidth = aRect.GetWidth();
250 [ + - ]: 113828 : const double fHeight = aRect.GetHeight();
251 : 113828 : double fDX = fWidth * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) );
252 : 113828 : double fDY = fHeight * fabs( cos( fAngle ) ) + fWidth * fabs( sin( fAngle ) );
253 : :
254 : 113828 : fDX = ( fDX - fWidth ) * 0.5 + 0.5;
255 : 113828 : fDY = ( fDY - fHeight ) * 0.5 + 0.5;
256 : :
257 : 113828 : aRect.Left() -= (long) fDX;
258 : 113828 : aRect.Right() += (long) fDX;
259 : 113828 : aRect.Top() -= (long) fDY;
260 : 113828 : aRect.Bottom() += (long) fDY;
261 : :
262 : 113828 : rBoundRect = aRect;
263 [ + - ]: 113828 : rCenter = rRect.Center();
264 : : }
265 : : else
266 : : {
267 [ # # ][ # # ]: 0 : if( GetStyle() == GradientStyle_SQUARE || GetStyle() == GradientStyle_RECT )
[ # # ]
268 : : {
269 : 0 : const double fAngle = nAngle * F_PI1800;
270 [ # # ]: 0 : const double fWidth = aRect.GetWidth();
271 [ # # ]: 0 : const double fHeight = aRect.GetHeight();
272 : 0 : double fDX = fWidth * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) );
273 : 0 : double fDY = fHeight * fabs( cos( fAngle ) ) + fWidth * fabs( sin( fAngle ) );
274 : :
275 : 0 : fDX = ( fDX - fWidth ) * 0.5 + 0.5;
276 : 0 : fDY = ( fDY - fHeight ) * 0.5 + 0.5;
277 : :
278 : 0 : aRect.Left() -= (long) fDX;
279 : 0 : aRect.Right() += (long) fDX;
280 : 0 : aRect.Top() -= (long) fDY;
281 : 0 : aRect.Bottom() += (long) fDY;
282 : : }
283 : :
284 [ # # ]: 0 : Size aSize( aRect.GetSize() );
285 : :
286 [ # # ]: 0 : if( GetStyle() == GradientStyle_RADIAL )
287 : : {
288 : : // Radien-Berechnung fuer Kreis
289 : 0 : aSize.Width() = (long)(0.5 + sqrt((double)aSize.Width()*(double)aSize.Width() + (double)aSize.Height()*(double)aSize.Height()));
290 : 0 : aSize.Height() = aSize.Width();
291 : : }
292 [ # # ]: 0 : else if( GetStyle() == GradientStyle_ELLIPTICAL )
293 : : {
294 : : // Radien-Berechnung fuer Ellipse
295 : 0 : aSize.Width() = (long)( 0.5 + (double) aSize.Width() * 1.4142 );
296 : 0 : aSize.Height() = (long)( 0.5 + (double) aSize.Height() * 1.4142 );
297 : : }
298 [ # # ]: 0 : else if( GetStyle() == GradientStyle_SQUARE )
299 : : {
300 [ # # ]: 0 : if ( aSize.Width() > aSize.Height() )
301 : 0 : aSize.Height() = aSize.Width();
302 : : else
303 : 0 : aSize.Width() = aSize.Height();
304 : : }
305 : :
306 : : // neue Mittelpunkte berechnen
307 [ # # ]: 0 : long nZWidth = aRect.GetWidth() * (long) GetOfsX() / 100;
308 [ # # ]: 0 : long nZHeight = aRect.GetHeight() * (long) GetOfsY() / 100;
309 : 0 : long nBorderX = (long) GetBorder() * aSize.Width() / 100;
310 : 0 : long nBorderY = (long) GetBorder() * aSize.Height() / 100;
311 : 0 : rCenter = Point( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
312 : :
313 : : // Rand beruecksichtigen
314 : 0 : aSize.Width() -= nBorderX;
315 : 0 : aSize.Height() -= nBorderY;
316 : :
317 : : // Ausgaberechteck neu setzen
318 : 0 : aRect.Left() = rCenter.X() - ( aSize.Width() >> 1 );
319 : 0 : aRect.Top() = rCenter.Y() - ( aSize.Height() >> 1 );
320 : :
321 [ # # ]: 0 : aRect.SetSize( aSize );
322 : 0 : rBoundRect = aRect;
323 : : }
324 : 113828 : }
325 : :
326 : : // -----------------------------------------------------------------------
327 : :
328 : 0 : Gradient& Gradient::operator=( const Gradient& rGradient )
329 : : {
330 : : DBG_CHKTHIS( Gradient, NULL );
331 : : DBG_CHKOBJ( &rGradient, Gradient, NULL );
332 : :
333 : : // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
334 : 0 : rGradient.mpImplGradient->mnRefCount++;
335 : :
336 : : // Wenn es die letzte Referenz ist, loeschen,
337 : : // sonst Referenzcounter decrementieren
338 [ # # ]: 0 : if ( mpImplGradient->mnRefCount == 1 )
339 : 0 : delete mpImplGradient;
340 : : else
341 : 0 : mpImplGradient->mnRefCount--;
342 : 0 : mpImplGradient = rGradient.mpImplGradient;
343 : :
344 : 0 : return *this;
345 : : }
346 : :
347 : : // -----------------------------------------------------------------------
348 : :
349 : 0 : sal_Bool Gradient::operator==( const Gradient& rGradient ) const
350 : : {
351 : : DBG_CHKTHIS( Gradient, NULL );
352 : : DBG_CHKOBJ( &rGradient, Gradient, NULL );
353 : :
354 [ # # ]: 0 : if ( mpImplGradient == rGradient.mpImplGradient )
355 : 0 : return sal_True;
356 : :
357 [ # # ][ # # ]: 0 : if ( (mpImplGradient->meStyle == rGradient.mpImplGradient->meStyle) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
[ # # ]
358 : : (mpImplGradient->mnAngle == rGradient.mpImplGradient->mnAngle) ||
359 : : (mpImplGradient->mnBorder == rGradient.mpImplGradient->mnBorder) ||
360 : : (mpImplGradient->mnOfsX == rGradient.mpImplGradient->mnOfsX) ||
361 : : (mpImplGradient->mnOfsY == rGradient.mpImplGradient->mnOfsY) ||
362 : : (mpImplGradient->mnStepCount == rGradient.mpImplGradient->mnStepCount) ||
363 : : (mpImplGradient->mnIntensityStart == rGradient.mpImplGradient->mnIntensityStart) ||
364 : : (mpImplGradient->mnIntensityEnd == rGradient.mpImplGradient->mnIntensityEnd) ||
365 : 0 : (mpImplGradient->maStartColor == rGradient.mpImplGradient->maStartColor) ||
366 : 0 : (mpImplGradient->maEndColor == rGradient.mpImplGradient->maEndColor) )
367 : 0 : return sal_True;
368 : : else
369 : 0 : return sal_False;
370 : : }
371 : :
372 : 0 : SvStream& operator>>( SvStream& rIStm, Impl_Gradient& rImpl_Gradient )
373 : : {
374 [ # # ]: 0 : VersionCompat aCompat( rIStm, STREAM_READ );
375 : : sal_uInt16 nTmp16;
376 : :
377 [ # # ]: 0 : rIStm >> nTmp16; rImpl_Gradient.meStyle = (GradientStyle) nTmp16;
378 : :
379 [ # # ]: 0 : rIStm >> rImpl_Gradient.maStartColor >>
380 [ # # ]: 0 : rImpl_Gradient.maEndColor >>
381 [ # # ]: 0 : rImpl_Gradient.mnAngle >>
382 [ # # ]: 0 : rImpl_Gradient.mnBorder >>
383 [ # # ]: 0 : rImpl_Gradient.mnOfsX >>
384 [ # # ]: 0 : rImpl_Gradient.mnOfsY >>
385 [ # # ]: 0 : rImpl_Gradient.mnIntensityStart >>
386 [ # # ]: 0 : rImpl_Gradient.mnIntensityEnd >>
387 [ # # ]: 0 : rImpl_Gradient.mnStepCount;
388 : :
389 [ # # ]: 0 : return rIStm;
390 : : }
391 : :
392 : : // -----------------------------------------------------------------------
393 : :
394 : 0 : SvStream& operator<<( SvStream& rOStm, const Impl_Gradient& rImpl_Gradient )
395 : : {
396 [ # # ]: 0 : VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
397 : :
398 [ # # ]: 0 : rOStm << (sal_uInt16) rImpl_Gradient.meStyle <<
399 [ # # ]: 0 : rImpl_Gradient.maStartColor <<
400 [ # # ]: 0 : rImpl_Gradient.maEndColor <<
401 [ # # ]: 0 : rImpl_Gradient.mnAngle <<
402 [ # # ]: 0 : rImpl_Gradient.mnBorder <<
403 [ # # ]: 0 : rImpl_Gradient.mnOfsX <<
404 [ # # ]: 0 : rImpl_Gradient.mnOfsY <<
405 [ # # ]: 0 : rImpl_Gradient.mnIntensityStart <<
406 [ # # ]: 0 : rImpl_Gradient.mnIntensityEnd <<
407 [ # # ]: 0 : rImpl_Gradient.mnStepCount;
408 : :
409 [ # # ]: 0 : return rOStm;
410 : : }
411 : :
412 : : // -----------------------------------------------------------------------
413 : :
414 : 0 : SvStream& operator>>( SvStream& rIStm, Gradient& rGradient )
415 : : {
416 : 0 : rGradient.MakeUnique();
417 : 0 : return( rIStm >> *rGradient.mpImplGradient );
418 : : }
419 : :
420 : : // -----------------------------------------------------------------------
421 : :
422 : 0 : SvStream& operator<<( SvStream& rOStm, const Gradient& rGradient )
423 : : {
424 : 0 : return( rOStm << *rGradient.mpImplGradient );
425 : : }
426 : :
427 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|