LibreOffice Module vcl (master)  1
gdi/gradient.cxx
Go to the documentation of this file.
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/gen.hxx>
21 #include <vcl/gradient.hxx>
22 
24 {
25 public:
30  sal_uInt16 mnBorder;
31  sal_uInt16 mnOfsX;
32  sal_uInt16 mnOfsY;
33  sal_uInt16 mnIntensityStart;
34  sal_uInt16 mnIntensityEnd;
35  sal_uInt16 mnStepCount;
36 
37  Impl()
38  : meStyle (GradientStyle::Linear)
39  , maStartColor(COL_BLACK)
40  , maEndColor(COL_WHITE)
41  , mnAngle(0)
42  , mnBorder(0)
43  , mnOfsX(50)
44  , mnOfsY(50)
45  , mnIntensityStart(100)
46  , mnIntensityEnd(100)
47  , mnStepCount(0)
48  {
49  }
50 
51  Impl(const Impl& rImplGradient)
52  : meStyle (rImplGradient.meStyle)
53  , maStartColor(rImplGradient.maStartColor)
54  , maEndColor(rImplGradient.maEndColor)
55  , mnAngle(rImplGradient.mnAngle)
56  , mnBorder(rImplGradient.mnBorder)
57  , mnOfsX(rImplGradient.mnOfsX)
58  , mnOfsY(rImplGradient.mnOfsY)
59  , mnIntensityStart(rImplGradient.mnIntensityStart)
60  , mnIntensityEnd(rImplGradient.mnIntensityEnd)
61  , mnStepCount(rImplGradient.mnStepCount)
62  {
63  }
64 
65  bool operator==(const Impl& rImpl_Gradient) const
66  {
67  return (meStyle == rImpl_Gradient.meStyle)
68  && (mnAngle == rImpl_Gradient.mnAngle)
69  && (mnBorder == rImpl_Gradient.mnBorder)
70  && (mnOfsX == rImpl_Gradient.mnOfsX)
71  && (mnOfsY == rImpl_Gradient.mnOfsY)
72  && (mnStepCount == rImpl_Gradient.mnStepCount)
73  && (mnIntensityStart == rImpl_Gradient.mnIntensityStart)
74  && (mnIntensityEnd == rImpl_Gradient.mnIntensityEnd)
75  && (maStartColor == rImpl_Gradient.maStartColor)
76  && (maEndColor == rImpl_Gradient.maEndColor);
77  }
78 };
79 
80 Gradient::Gradient() = default;
81 
82 Gradient::Gradient( const Gradient& ) = default;
83 
84 Gradient::Gradient( Gradient&& ) = default;
85 
87  const Color& rStartColor, const Color& rEndColor ) :
88  mpImplGradient()
89 {
90  mpImplGradient->meStyle = eStyle;
91  mpImplGradient->maStartColor = rStartColor;
92  mpImplGradient->maEndColor = rEndColor;
93 }
94 
95 Gradient::~Gradient() = default;
96 
97 
99 {
100  return mpImplGradient->meStyle;
101 }
102 
104 {
105  mpImplGradient->meStyle = eStyle;
106 }
107 
109 {
110  return mpImplGradient->maStartColor;
111 }
112 
113 void Gradient::SetStartColor( const Color& rColor )
114 {
115  mpImplGradient->maStartColor = rColor;
116 }
117 
119 {
120  return mpImplGradient->maEndColor;
121 }
122 
123 void Gradient::SetEndColor( const Color& rColor )
124 {
125  mpImplGradient->maEndColor = rColor;
126 }
127 
129 {
130  return mpImplGradient->mnAngle;
131 }
132 
134 {
135  mpImplGradient->mnAngle = nAngle;
136 }
137 
138 sal_uInt16 Gradient::GetBorder() const
139 {
140  return mpImplGradient->mnBorder;
141 }
142 
143 void Gradient::SetBorder( sal_uInt16 nBorder )
144 {
145  mpImplGradient->mnBorder = nBorder;
146 }
147 
148 sal_uInt16 Gradient::GetOfsX() const
149 {
150  return mpImplGradient->mnOfsX;
151 }
152 
153 void Gradient::SetOfsX( sal_uInt16 nOfsX )
154 {
155  mpImplGradient->mnOfsX = nOfsX;
156 }
157 
158 sal_uInt16 Gradient::GetOfsY() const
159 {
160  return mpImplGradient->mnOfsY;
161 }
162 
163 void Gradient::SetOfsY( sal_uInt16 nOfsY )
164 {
165  mpImplGradient->mnOfsY = nOfsY;
166 }
167 
168 sal_uInt16 Gradient::GetStartIntensity() const
169 {
170  return mpImplGradient->mnIntensityStart;
171 }
172 
173 void Gradient::SetStartIntensity( sal_uInt16 nIntens )
174 {
175  mpImplGradient->mnIntensityStart = nIntens;
176 }
177 
178 sal_uInt16 Gradient::GetEndIntensity() const
179 {
180  return mpImplGradient->mnIntensityEnd;
181 }
182 
183 void Gradient::SetEndIntensity( sal_uInt16 nIntens )
184 {
185  mpImplGradient->mnIntensityEnd = nIntens;
186 }
187 
188 sal_uInt16 Gradient::GetSteps() const
189 {
190  return mpImplGradient->mnStepCount;
191 }
192 
193 void Gradient::SetSteps( sal_uInt16 nSteps )
194 {
195  mpImplGradient->mnStepCount = nSteps;
196 }
197 
198 void Gradient::GetBoundRect( const tools::Rectangle& rRect, tools::Rectangle& rBoundRect, Point& rCenter ) const
199 {
200  tools::Rectangle aRect( rRect );
201  Degree10 nAngle = GetAngle() % Degree10(3600);
202 
203  if( GetStyle() == GradientStyle::Linear || GetStyle() == GradientStyle::Axial )
204  {
205  const double fAngle = nAngle.get() * F_PI1800;
206  const double fWidth = aRect.GetWidth();
207  const double fHeight = aRect.GetHeight();
208  double fDX = fWidth * fabs( cos( fAngle ) ) +
209  fHeight * fabs( sin( fAngle ) );
210  double fDY = fHeight * fabs( cos( fAngle ) ) +
211  fWidth * fabs( sin( fAngle ) );
212  fDX = (fDX - fWidth) * 0.5 + 0.5;
213  fDY = (fDY - fHeight) * 0.5 + 0.5;
214  aRect.AdjustLeft( -static_cast<tools::Long>(fDX) );
215  aRect.AdjustRight(static_cast<tools::Long>(fDX) );
216  aRect.AdjustTop( -static_cast<tools::Long>(fDY) );
217  aRect.AdjustBottom(static_cast<tools::Long>(fDY) );
218 
219  rBoundRect = aRect;
220  rCenter = rRect.Center();
221  }
222  else
223  {
224  if( GetStyle() == GradientStyle::Square || GetStyle() == GradientStyle::Rect )
225  {
226  const double fAngle = nAngle.get() * F_PI1800;
227  const double fWidth = aRect.GetWidth();
228  const double fHeight = aRect.GetHeight();
229  double fDX = fWidth * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) );
230  double fDY = fHeight * fabs( cos( fAngle ) ) + fWidth * fabs( sin( fAngle ) );
231 
232  fDX = ( fDX - fWidth ) * 0.5 + 0.5;
233  fDY = ( fDY - fHeight ) * 0.5 + 0.5;
234 
235  aRect.AdjustLeft( -static_cast<tools::Long>(fDX) );
236  aRect.AdjustRight(static_cast<tools::Long>(fDX) );
237  aRect.AdjustTop( -static_cast<tools::Long>(fDY) );
238  aRect.AdjustBottom(static_cast<tools::Long>(fDY) );
239  }
240 
241  Size aSize( aRect.GetSize() );
242 
243  if( GetStyle() == GradientStyle::Radial )
244  {
245  // Calculation of radii for circle
246  aSize.setWidth( static_cast<tools::Long>(0.5 + sqrt(static_cast<double>(aSize.Width())*static_cast<double>(aSize.Width()) + static_cast<double>(aSize.Height())*static_cast<double>(aSize.Height()))) );
247  aSize.setHeight( aSize.Width() );
248  }
249  else if( GetStyle() == GradientStyle::Elliptical )
250  {
251  // Calculation of radii for ellipse
252  aSize.setWidth( static_cast<tools::Long>( 0.5 + static_cast<double>(aSize.Width()) * 1.4142 ) );
253  aSize.setHeight( static_cast<tools::Long>( 0.5 + static_cast<double>(aSize.Height()) * 1.4142 ) );
254  }
255 
256  // Calculate new centers
257  tools::Long nZWidth = aRect.GetWidth() * static_cast<tools::Long>(GetOfsX()) / 100;
258  tools::Long nZHeight = aRect.GetHeight() * static_cast<tools::Long>(GetOfsY()) / 100;
259  tools::Long nBorderX = static_cast<tools::Long>(GetBorder()) * aSize.Width() / 100;
260  tools::Long nBorderY = static_cast<tools::Long>(GetBorder()) * aSize.Height() / 100;
261  rCenter = Point( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
262 
263  // Respect borders
264  aSize.AdjustWidth( -nBorderX );
265  aSize.AdjustHeight( -nBorderY );
266 
267  // Recalculate output rectangle
268  aRect.SetLeft( rCenter.X() - ( aSize.Width() >> 1 ) );
269  aRect.SetTop( rCenter.Y() - ( aSize.Height() >> 1 ) );
270 
271  aRect.SetSize( aSize );
272  rBoundRect = aRect;
273  }
274 }
275 
276 Gradient& Gradient::operator=( const Gradient& ) = default;
277 
278 Gradient& Gradient::operator=( Gradient&& ) = default;
279 
280 bool Gradient::operator==( const Gradient& rGradient ) const
281 {
282  return mpImplGradient == rGradient.mpImplGradient;
283 }
284 
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetEndColor(const Color &rColor)
GradientStyle GetStyle() const
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
void setWidth(tools::Long nWidth)
sal_uInt16 GetOfsY() const
Degree10 mnAngle
long Long
#define F_PI1800
sal_uInt16 GetBorder() const
tools::Long GetWidth() const
void SetBorder(sal_uInt16 nBorder)
sal_uInt16 mnIntensityEnd
void SetEndIntensity(sal_uInt16 nIntens)
Gradient & operator=(const Gradient &rGradient)
void SetSteps(sal_uInt16 nSteps)
tools::Long Left() const
void SetOfsY(sal_uInt16 nOfsY)
void SetLeft(tools::Long v)
void SetStartColor(const Color &rColor)
GradientStyle
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
UNDERLYING_TYPE get() const
void GetBoundRect(const tools::Rectangle &rRect, tools::Rectangle &rBoundRect, Point &rCenter) const
void SetSize(const Size &rSize)
sal_uInt16 GetOfsX() const
Impl(const Impl &rImplGradient)
sal_uInt16 GetEndIntensity() const
void SetTop(tools::Long v)
sal_uInt16 mnOfsX
sal_uInt16 mnStepCount
bool operator==(const Gradient &rGradient) const
tools::Long Top() const
void SetOfsX(sal_uInt16 nOfsX)
Size GetSize() const
sal_uInt16 GetSteps() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
const Color & GetStartColor() const
void SetAngle(Degree10 nAngle)
Degree10 GetAngle() const
::o3tl::cow_wrapper< Impl > mpImplGradient
Definition: gradient.hxx:40
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
const Color & GetEndColor() const
GradientStyle meStyle
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
sal_uInt16 mnIntensityStart
sal_uInt16 mnOfsY
tools::Long GetHeight() const
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
void SetStyle(GradientStyle eStyle)
sal_uInt16 GetStartIntensity() const
bool operator==(const Impl &rImpl_Gradient) const
sal_uInt16 mnBorder
void SetStartIntensity(sal_uInt16 nIntens)
Point Center() const