1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <tools/stream.hxx>
21 #include <tools/vcompat.hxx>
22 #include <tools/gen.hxx>
23 #include <vcl/gradient.hxx>
25 Impl_Gradient::Impl_Gradient() :
26 maStartColor( COL_BLACK
),
27 maEndColor( COL_WHITE
)
29 meStyle
= GradientStyle::Linear
;
34 mnIntensityStart
= 100;
39 Impl_Gradient::Impl_Gradient( const Impl_Gradient
& rImplGradient
) :
40 maStartColor( rImplGradient
.maStartColor
),
41 maEndColor( rImplGradient
.maEndColor
)
43 meStyle
= rImplGradient
.meStyle
;
44 mnAngle
= rImplGradient
.mnAngle
;
45 mnBorder
= rImplGradient
.mnBorder
;
46 mnOfsX
= rImplGradient
.mnOfsX
;
47 mnOfsY
= rImplGradient
.mnOfsY
;
48 mnIntensityStart
= rImplGradient
.mnIntensityStart
;
49 mnIntensityEnd
= rImplGradient
.mnIntensityEnd
;
50 mnStepCount
= rImplGradient
.mnStepCount
;
53 bool Impl_Gradient::operator==( const Impl_Gradient
& rImpl_Gradient
) const
55 return (meStyle
== rImpl_Gradient
.meStyle
) &&
56 (mnAngle
== rImpl_Gradient
.mnAngle
) &&
57 (mnBorder
== rImpl_Gradient
.mnBorder
) &&
58 (mnOfsX
== rImpl_Gradient
.mnOfsX
) &&
59 (mnOfsY
== rImpl_Gradient
.mnOfsY
) &&
60 (mnStepCount
== rImpl_Gradient
.mnStepCount
) &&
61 (mnIntensityStart
== rImpl_Gradient
.mnIntensityStart
) &&
62 (mnIntensityEnd
== rImpl_Gradient
.mnIntensityEnd
) &&
63 (maStartColor
== rImpl_Gradient
.maStartColor
) &&
64 (maEndColor
== rImpl_Gradient
.maEndColor
);
67 Gradient::Gradient() :
72 Gradient::Gradient( const Gradient
& rGradient
) :
73 mpImplGradient( rGradient
.mpImplGradient
)
77 Gradient::Gradient( Gradient
&& rGradient
) :
78 mpImplGradient( std::move(rGradient
.mpImplGradient
) )
82 Gradient::Gradient( GradientStyle eStyle
,
83 const Color
& rStartColor
, const Color
& rEndColor
) :
86 mpImplGradient
->meStyle
= eStyle
;
87 mpImplGradient
->maStartColor
= rStartColor
;
88 mpImplGradient
->maEndColor
= rEndColor
;
95 void Gradient::SetStyle( GradientStyle eStyle
)
97 mpImplGradient
->meStyle
= eStyle
;
100 void Gradient::SetStartColor( const Color
& rColor
)
102 mpImplGradient
->maStartColor
= rColor
;
105 void Gradient::SetEndColor( const Color
& rColor
)
107 mpImplGradient
->maEndColor
= rColor
;
110 void Gradient::SetAngle( sal_uInt16 nAngle
)
112 mpImplGradient
->mnAngle
= nAngle
;
115 void Gradient::SetBorder( sal_uInt16 nBorder
)
117 mpImplGradient
->mnBorder
= nBorder
;
120 void Gradient::SetOfsX( sal_uInt16 nOfsX
)
122 mpImplGradient
->mnOfsX
= nOfsX
;
125 void Gradient::SetOfsY( sal_uInt16 nOfsY
)
127 mpImplGradient
->mnOfsY
= nOfsY
;
130 void Gradient::SetStartIntensity( sal_uInt16 nIntens
)
132 mpImplGradient
->mnIntensityStart
= nIntens
;
135 void Gradient::SetEndIntensity( sal_uInt16 nIntens
)
137 mpImplGradient
->mnIntensityEnd
= nIntens
;
140 void Gradient::SetSteps( sal_uInt16 nSteps
)
142 mpImplGradient
->mnStepCount
= nSteps
;
145 void Gradient::GetBoundRect( const tools::Rectangle
& rRect
, tools::Rectangle
& rBoundRect
, Point
& rCenter
) const
147 tools::Rectangle
aRect( rRect
);
148 sal_uInt16 nAngle
= GetAngle() % 3600;
150 if( GetStyle() == GradientStyle::Linear
|| GetStyle() == GradientStyle::Axial
)
152 const double fAngle
= nAngle
* F_PI1800
;
153 const double fWidth
= aRect
.GetWidth();
154 const double fHeight
= aRect
.GetHeight();
155 double fDX
= fWidth
* fabs( cos( fAngle
) ) +
156 fHeight
* fabs( sin( fAngle
) );
157 double fDY
= fHeight
* fabs( cos( fAngle
) ) +
158 fWidth
* fabs( sin( fAngle
) );
159 fDX
= (fDX
- fWidth
) * 0.5 + 0.5;
160 fDY
= (fDY
- fHeight
) * 0.5 + 0.5;
161 aRect
.Left() -= (long) fDX
;
162 aRect
.Right() += (long) fDX
;
163 aRect
.Top() -= (long) fDY
;
164 aRect
.Bottom() += (long) fDY
;
167 rCenter
= rRect
.Center();
171 if( GetStyle() == GradientStyle::Square
|| GetStyle() == GradientStyle::Rect
)
173 const double fAngle
= nAngle
* F_PI1800
;
174 const double fWidth
= aRect
.GetWidth();
175 const double fHeight
= aRect
.GetHeight();
176 double fDX
= fWidth
* fabs( cos( fAngle
) ) + fHeight
* fabs( sin( fAngle
) );
177 double fDY
= fHeight
* fabs( cos( fAngle
) ) + fWidth
* fabs( sin( fAngle
) );
179 fDX
= ( fDX
- fWidth
) * 0.5 + 0.5;
180 fDY
= ( fDY
- fHeight
) * 0.5 + 0.5;
182 aRect
.Left() -= (long) fDX
;
183 aRect
.Right() += (long) fDX
;
184 aRect
.Top() -= (long) fDY
;
185 aRect
.Bottom() += (long) fDY
;
188 Size
aSize( aRect
.GetSize() );
190 if( GetStyle() == GradientStyle::Radial
)
192 // Calculation of radii for circle
193 aSize
.Width() = (long)(0.5 + sqrt((double)aSize
.Width()*(double)aSize
.Width() + (double)aSize
.Height()*(double)aSize
.Height()));
194 aSize
.Height() = aSize
.Width();
196 else if( GetStyle() == GradientStyle::Elliptical
)
198 // Calculation of radii for ellipse
199 aSize
.Width() = (long)( 0.5 + (double) aSize
.Width() * 1.4142 );
200 aSize
.Height() = (long)( 0.5 + (double) aSize
.Height() * 1.4142 );
203 // Calculate new centers
204 long nZWidth
= aRect
.GetWidth() * (long) GetOfsX() / 100;
205 long nZHeight
= aRect
.GetHeight() * (long) GetOfsY() / 100;
206 long nBorderX
= (long) GetBorder() * aSize
.Width() / 100;
207 long nBorderY
= (long) GetBorder() * aSize
.Height() / 100;
208 rCenter
= Point( aRect
.Left() + nZWidth
, aRect
.Top() + nZHeight
);
211 aSize
.Width() -= nBorderX
;
212 aSize
.Height() -= nBorderY
;
214 // Recalculate output rectangle
215 aRect
.Left() = rCenter
.X() - ( aSize
.Width() >> 1 );
216 aRect
.Top() = rCenter
.Y() - ( aSize
.Height() >> 1 );
218 aRect
.SetSize( aSize
);
223 Gradient
& Gradient::operator=( const Gradient
& rGradient
)
225 mpImplGradient
= rGradient
.mpImplGradient
;
230 Gradient
& Gradient::operator=( Gradient
&& rGradient
)
232 mpImplGradient
= std::move(rGradient
.mpImplGradient
);
236 bool Gradient::operator==( const Gradient
& rGradient
) const
238 return mpImplGradient
== rGradient
.mpImplGradient
;
241 SvStream
& ReadGradient( SvStream
& rIStm
, Gradient
& rGradient
)
243 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
246 rIStm
.ReadUInt16( nTmp16
); rGradient
.mpImplGradient
->meStyle
= (GradientStyle
) nTmp16
;
248 ReadColor( rIStm
, rGradient
.mpImplGradient
->maStartColor
);
249 ReadColor( rIStm
, rGradient
.mpImplGradient
->maEndColor
);
250 rIStm
.ReadUInt16( rGradient
.mpImplGradient
->mnAngle
)
251 .ReadUInt16( rGradient
.mpImplGradient
->mnBorder
)
252 .ReadUInt16( rGradient
.mpImplGradient
->mnOfsX
)
253 .ReadUInt16( rGradient
.mpImplGradient
->mnOfsY
)
254 .ReadUInt16( rGradient
.mpImplGradient
->mnIntensityStart
)
255 .ReadUInt16( rGradient
.mpImplGradient
->mnIntensityEnd
)
256 .ReadUInt16( rGradient
.mpImplGradient
->mnStepCount
);
261 SvStream
& WriteGradient( SvStream
& rOStm
, const Gradient
& rGradient
)
263 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 1 );
265 rOStm
.WriteUInt16( (sal_uInt16
)rGradient
.mpImplGradient
->meStyle
);
266 WriteColor( rOStm
, rGradient
.mpImplGradient
->maStartColor
);
267 WriteColor( rOStm
, rGradient
.mpImplGradient
->maEndColor
);
268 rOStm
.WriteUInt16( rGradient
.mpImplGradient
->mnAngle
)
269 .WriteUInt16( rGradient
.mpImplGradient
->mnBorder
)
270 .WriteUInt16( rGradient
.mpImplGradient
->mnOfsX
)
271 .WriteUInt16( rGradient
.mpImplGradient
->mnOfsY
)
272 .WriteUInt16( rGradient
.mpImplGradient
->mnIntensityStart
)
273 .WriteUInt16( rGradient
.mpImplGradient
->mnIntensityEnd
)
274 .WriteUInt16( rGradient
.mpImplGradient
->mnStepCount
);
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */