Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / gdi / gradient.cxx
blob191c3852dc743287bc0408795e7a645e4f81e399
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
30 mnAngle = 0;
31 mnBorder = 0;
32 mnOfsX = 50;
33 mnOfsY = 50;
34 mnIntensityStart = 100;
35 mnIntensityEnd = 100;
36 mnStepCount = 0;
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() :
68 mpImplGradient()
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 ) :
84 mpImplGradient()
86 mpImplGradient->meStyle = eStyle;
87 mpImplGradient->maStartColor = rStartColor;
88 mpImplGradient->maEndColor = rEndColor;
91 Gradient::~Gradient()
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;
166 rBoundRect = aRect;
167 rCenter = rRect.Center();
169 else
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 );
210 // Respect borders
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 );
219 rBoundRect = aRect;
223 Gradient& Gradient::operator=( const Gradient& rGradient )
225 mpImplGradient = rGradient.mpImplGradient;
227 return *this;
230 Gradient& Gradient::operator=( Gradient&& rGradient )
232 mpImplGradient = std::move(rGradient.mpImplGradient);
233 return *this;
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 );
244 sal_uInt16 nTmp16;
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 );
258 return rIStm;
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 );
276 return rOStm;
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */