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  maStartColor( COL_BLACK ),
25  maEndColor( COL_WHITE )
26 {
27  meStyle = GradientStyle::Linear;
28  mnAngle = 0;
29  mnBorder = 0;
30  mnOfsX = 50;
31  mnOfsY = 50;
32  mnIntensityStart = 100;
33  mnIntensityEnd = 100;
34  mnStepCount = 0;
35 }
36 
38  maStartColor( rImplGradient.maStartColor ),
39  maEndColor( rImplGradient.maEndColor )
40 {
41  meStyle = rImplGradient.meStyle;
42  mnAngle = rImplGradient.mnAngle;
43  mnBorder = rImplGradient.mnBorder;
44  mnOfsX = rImplGradient.mnOfsX;
45  mnOfsY = rImplGradient.mnOfsY;
46  mnIntensityStart = rImplGradient.mnIntensityStart;
47  mnIntensityEnd = rImplGradient.mnIntensityEnd;
48  mnStepCount = rImplGradient.mnStepCount;
49 }
50 
51 bool Impl_Gradient::operator==( const Impl_Gradient& rImpl_Gradient ) const
52 {
53  return (meStyle == rImpl_Gradient.meStyle) &&
54  (mnAngle == rImpl_Gradient.mnAngle) &&
55  (mnBorder == rImpl_Gradient.mnBorder) &&
56  (mnOfsX == rImpl_Gradient.mnOfsX) &&
57  (mnOfsY == rImpl_Gradient.mnOfsY) &&
58  (mnStepCount == rImpl_Gradient.mnStepCount) &&
59  (mnIntensityStart == rImpl_Gradient.mnIntensityStart) &&
60  (mnIntensityEnd == rImpl_Gradient.mnIntensityEnd) &&
61  (maStartColor == rImpl_Gradient.maStartColor) &&
62  (maEndColor == rImpl_Gradient.maEndColor);
63 }
64 
65 Gradient::Gradient() = default;
66 
67 Gradient::Gradient( const Gradient& ) = default;
68 
69 Gradient::Gradient( Gradient&& ) = default;
70 
72  const Color& rStartColor, const Color& rEndColor ) :
73  mpImplGradient()
74 {
75  mpImplGradient->meStyle = eStyle;
76  mpImplGradient->maStartColor = rStartColor;
77  mpImplGradient->maEndColor = rEndColor;
78 }
79 
80 Gradient::~Gradient() = default;
81 
83 {
84  mpImplGradient->meStyle = eStyle;
85 }
86 
87 void Gradient::SetStartColor( const Color& rColor )
88 {
89  mpImplGradient->maStartColor = rColor;
90 }
91 
92 void Gradient::SetEndColor( const Color& rColor )
93 {
94  mpImplGradient->maEndColor = rColor;
95 }
96 
97 void Gradient::SetAngle( sal_uInt16 nAngle )
98 {
99  mpImplGradient->mnAngle = nAngle;
100 }
101 
102 void Gradient::SetBorder( sal_uInt16 nBorder )
103 {
104  mpImplGradient->mnBorder = nBorder;
105 }
106 
107 void Gradient::SetOfsX( sal_uInt16 nOfsX )
108 {
109  mpImplGradient->mnOfsX = nOfsX;
110 }
111 
112 void Gradient::SetOfsY( sal_uInt16 nOfsY )
113 {
114  mpImplGradient->mnOfsY = nOfsY;
115 }
116 
117 void Gradient::SetStartIntensity( sal_uInt16 nIntens )
118 {
119  mpImplGradient->mnIntensityStart = nIntens;
120 }
121 
122 void Gradient::SetEndIntensity( sal_uInt16 nIntens )
123 {
124  mpImplGradient->mnIntensityEnd = nIntens;
125 }
126 
127 void Gradient::SetSteps( sal_uInt16 nSteps )
128 {
129  mpImplGradient->mnStepCount = nSteps;
130 }
131 
132 void Gradient::GetBoundRect( const tools::Rectangle& rRect, tools::Rectangle& rBoundRect, Point& rCenter ) const
133 {
134  tools::Rectangle aRect( rRect );
135  sal_uInt16 nAngle = GetAngle() % 3600;
136 
137  if( GetStyle() == GradientStyle::Linear || GetStyle() == GradientStyle::Axial )
138  {
139  const double fAngle = nAngle * F_PI1800;
140  const double fWidth = aRect.GetWidth();
141  const double fHeight = aRect.GetHeight();
142  double fDX = fWidth * fabs( cos( fAngle ) ) +
143  fHeight * fabs( sin( fAngle ) );
144  double fDY = fHeight * fabs( cos( fAngle ) ) +
145  fWidth * fabs( sin( fAngle ) );
146  fDX = (fDX - fWidth) * 0.5 + 0.5;
147  fDY = (fDY - fHeight) * 0.5 + 0.5;
148  aRect.AdjustLeft( -static_cast<long>(fDX) );
149  aRect.AdjustRight(static_cast<long>(fDX) );
150  aRect.AdjustTop( -static_cast<long>(fDY) );
151  aRect.AdjustBottom(static_cast<long>(fDY) );
152 
153  rBoundRect = aRect;
154  rCenter = rRect.Center();
155  }
156  else
157  {
158  if( GetStyle() == GradientStyle::Square || GetStyle() == GradientStyle::Rect )
159  {
160  const double fAngle = nAngle * F_PI1800;
161  const double fWidth = aRect.GetWidth();
162  const double fHeight = aRect.GetHeight();
163  double fDX = fWidth * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) );
164  double fDY = fHeight * fabs( cos( fAngle ) ) + fWidth * fabs( sin( fAngle ) );
165 
166  fDX = ( fDX - fWidth ) * 0.5 + 0.5;
167  fDY = ( fDY - fHeight ) * 0.5 + 0.5;
168 
169  aRect.AdjustLeft( -static_cast<long>(fDX) );
170  aRect.AdjustRight(static_cast<long>(fDX) );
171  aRect.AdjustTop( -static_cast<long>(fDY) );
172  aRect.AdjustBottom(static_cast<long>(fDY) );
173  }
174 
175  Size aSize( aRect.GetSize() );
176 
177  if( GetStyle() == GradientStyle::Radial )
178  {
179  // Calculation of radii for circle
180  aSize.setWidth( static_cast<long>(0.5 + sqrt(static_cast<double>(aSize.Width())*static_cast<double>(aSize.Width()) + static_cast<double>(aSize.Height())*static_cast<double>(aSize.Height()))) );
181  aSize.setHeight( aSize.Width() );
182  }
183  else if( GetStyle() == GradientStyle::Elliptical )
184  {
185  // Calculation of radii for ellipse
186  aSize.setWidth( static_cast<long>( 0.5 + static_cast<double>(aSize.Width()) * 1.4142 ) );
187  aSize.setHeight( static_cast<long>( 0.5 + static_cast<double>(aSize.Height()) * 1.4142 ) );
188  }
189 
190  // Calculate new centers
191  long nZWidth = aRect.GetWidth() * static_cast<long>(GetOfsX()) / 100;
192  long nZHeight = aRect.GetHeight() * static_cast<long>(GetOfsY()) / 100;
193  long nBorderX = static_cast<long>(GetBorder()) * aSize.Width() / 100;
194  long nBorderY = static_cast<long>(GetBorder()) * aSize.Height() / 100;
195  rCenter = Point( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
196 
197  // Respect borders
198  aSize.AdjustWidth( -nBorderX );
199  aSize.AdjustHeight( -nBorderY );
200 
201  // Recalculate output rectangle
202  aRect.SetLeft( rCenter.X() - ( aSize.Width() >> 1 ) );
203  aRect.SetTop( rCenter.Y() - ( aSize.Height() >> 1 ) );
204 
205  aRect.SetSize( aSize );
206  rBoundRect = aRect;
207  }
208 }
209 
210 Gradient& Gradient::operator=( const Gradient& ) = default;
211 
212 Gradient& Gradient::operator=( Gradient&& ) = default;
213 
214 bool Gradient::operator==( const Gradient& rGradient ) const
215 {
216  return mpImplGradient == rGradient.mpImplGradient;
217 }
218 
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetEndColor(const Color &rColor)
long GetWidth() const
GradientStyle GetStyle() const
Definition: gradient.hxx:74
long GetHeight() const
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
sal_uInt16 GetOfsY() const
Definition: gradient.hxx:89
long AdjustLeft(long nHorzMoveDelta)
#define F_PI1800
sal_uInt16 GetBorder() const
Definition: gradient.hxx:85
void SetBorder(sal_uInt16 nBorder)
void SetEndIntensity(sal_uInt16 nIntens)
long AdjustBottom(long nVertMoveDelta)
sal_uInt16 mnOfsY
Definition: gradient.hxx:47
Gradient & operator=(const Gradient &rGradient)
void SetSteps(sal_uInt16 nSteps)
bool operator==(const Impl_Gradient &rImpl_Gradient) const
void SetOfsY(sal_uInt16 nOfsY)
void SetStartColor(const Color &rColor)
Color maStartColor
Definition: gradient.hxx:42
GradientStyle
long Top() const
GradientStyle meStyle
Definition: gradient.hxx:41
void GetBoundRect(const tools::Rectangle &rRect, tools::Rectangle &rBoundRect, Point &rCenter) const
void SetTop(long v)
sal_uInt16 GetAngle() const
Definition: gradient.hxx:82
Color maEndColor
Definition: gradient.hxx:43
void SetSize(const Size &rSize)
sal_uInt16 GetOfsX() const
Definition: gradient.hxx:87
sal_uInt16 mnBorder
Definition: gradient.hxx:45
sal_uInt16 mnStepCount
Definition: gradient.hxx:50
bool operator==(const Gradient &rGradient) const
void SetOfsX(sal_uInt16 nOfsX)
long X() const
Size GetSize() const
sal_uInt16 mnIntensityStart
Definition: gradient.hxx:48
::o3tl::cow_wrapper< Impl_Gradient > mpImplGradient
Definition: gradient.hxx:62
long AdjustRight(long nHorzMoveDelta)
void SetAngle(sal_uInt16 nAngle)
long AdjustTop(long nVertMoveDelta)
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
long Left() const
sal_uInt16 mnAngle
Definition: gradient.hxx:44
void SetLeft(long v)
void SetStyle(GradientStyle eStyle)
void setWidth(long nWidth)
sal_uInt16 mnOfsX
Definition: gradient.hxx:46
sal_uInt16 mnIntensityEnd
Definition: gradient.hxx:49
void SetStartIntensity(sal_uInt16 nIntens)
Point Center() const
long Y() const