LibreOffice Module drawinglayer (master) 1
fillgradientattribute.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
22
24{
26 {
27 public:
28 // data definitions
29 double mfBorder;
30 double mfOffsetX;
31 double mfOffsetY;
32 double mfAngle;
34 css::awt::GradientStyle meStyle;
35 sal_uInt16 mnSteps;
36
38 css::awt::GradientStyle eStyle,
39 double fBorder,
40 double fOffsetX,
41 double fOffsetY,
42 double fAngle,
43 const basegfx::BColorStops& rColorStops,
44 sal_uInt16 nSteps)
45 : mfBorder(fBorder),
46 mfOffsetX(fOffsetX),
47 mfOffsetY(fOffsetY),
48 mfAngle(fAngle),
49 maColorStops(rColorStops), // copy ColorStops
50 meStyle(eStyle),
51 mnSteps(nSteps)
52 {
53 // Correct the local ColorStops. That will guarantee that the
54 // content does contain no offsets < 0.0, > 1.0 or double
55 // ones, also secures sorted arrangement and checks for
56 // double colors, too (see there for more information).
57 // This is what the usages of this in primitives need.
58 // Since FillGradientAttribute is read-only doing this
59 // once here in the constructor is sufficient
61
62 // sortAndCorrectColorStops is rigid and can return
63 // an empty result. To keep things simple, add a single
64 // fallback value
65 if (maColorStops.empty())
66 {
67 maColorStops.emplace_back(0.0, basegfx::BColor());
68 }
69 }
70
72 : mfBorder(0.0),
73 mfOffsetX(0.0),
74 mfOffsetY(0.0),
75 mfAngle(0.0),
77 meStyle(css::awt::GradientStyle_LINEAR),
78 mnSteps(0)
79 {
80 // always add a fallback color, see above
81 maColorStops.emplace_back(0.0, basegfx::BColor());
82 }
83
84 // data read access
85 css::awt::GradientStyle getStyle() const { return meStyle; }
86 double getBorder() const { return mfBorder; }
87 double getOffsetX() const { return mfOffsetX; }
88 double getOffsetY() const { return mfOffsetY; }
89 double getAngle() const { return mfAngle; }
91 sal_uInt16 getSteps() const { return mnSteps; }
92
93 bool operator==(const ImpFillGradientAttribute& rCandidate) const
94 {
95 return (getStyle() == rCandidate.getStyle()
96 && getBorder() == rCandidate.getBorder()
97 && getOffsetX() == rCandidate.getOffsetX()
98 && getOffsetY() == rCandidate.getOffsetY()
99 && getAngle() == rCandidate.getAngle()
100 && getColorStops() == rCandidate.getColorStops()
101 && getSteps() == rCandidate.getSteps());
102 }
103 };
104
105 namespace
106 {
107 FillGradientAttribute::ImplType& theGlobalDefault()
108 {
109 static FillGradientAttribute::ImplType SINGLETON;
110 return SINGLETON;
111 }
112 }
113
115 css::awt::GradientStyle eStyle,
116 double fBorder,
117 double fOffsetX,
118 double fOffsetY,
119 double fAngle,
120 const basegfx::BColorStops& rColorStops,
121 sal_uInt16 nSteps)
122 : mpFillGradientAttribute(ImpFillGradientAttribute(
123 eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rColorStops, nSteps))
124 {
125 }
126
128 : mpFillGradientAttribute(theGlobalDefault())
129 {
130 }
131
133
135
137
139 {
140 return mpFillGradientAttribute.same_object(theGlobalDefault());
141 }
142
143 // MCGR: Check if rendering cannot be handled by old vcl stuff
145 {
146 // MCGR: If GradientStops are used, use decomposition since vcl is not able
147 // to render multi-color gradients
148 if (getColorStops().size() != 2)
149 {
150 return true;
151 }
152
153 // MCGR: If GradientStops do not start and stop at traditional Start/EndColor,
154 // use decomposition since vcl is not able to render this
155 if (!getColorStops().empty())
156 {
157 if (!basegfx::fTools::equalZero(getColorStops().front().getStopOffset())
158 || !basegfx::fTools::equal(getColorStops().back().getStopOffset(), 1.0))
159 {
160 return true;
161 }
162 }
163
164 // VCL should be able to handle all styles, but for tdf#133477 the VCL result
165 // is different from processing the gradient manually by drawinglayer
166 // (and the Writer unittest for it fails). Keep using the drawinglayer code
167 // until somebody founds out what's wrong and fixes it.
168 if (getStyle() != css::awt::GradientStyle_LINEAR
169 && getStyle() != css::awt::GradientStyle_AXIAL
170 && getStyle() != css::awt::GradientStyle_RADIAL)
171 {
172 return true;
173 }
174
175 return false;
176 }
177
179
181
183 {
184 // tdf#87509 default attr is always != non-default attr, even with same values
185 if(rCandidate.isDefault() != isDefault())
186 return false;
187
189 }
190
192 {
193 return mpFillGradientAttribute->getColorStops();
194 }
195
197 {
198 return mpFillGradientAttribute->getBorder();
199 }
200
202 {
203 return mpFillGradientAttribute->getOffsetX();
204 }
205
207 {
208 return mpFillGradientAttribute->getOffsetY();
209 }
210
212 {
213 return mpFillGradientAttribute->getAngle();
214 }
215
216 css::awt::GradientStyle FillGradientAttribute::getStyle() const
217 {
218 return mpFillGradientAttribute->getStyle();
219 }
220
222 {
223 return mpFillGradientAttribute->getSteps();
224 }
225
226} // end of namespace
227
228/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool operator==(const FillGradientAttribute &rCandidate) const
const basegfx::BColorStops & getColorStops() const
FillGradientAttribute & operator=(const FillGradientAttribute &)
o3tl::cow_wrapper< ImpFillGradientAttribute > ImplType
ImpFillGradientAttribute(css::awt::GradientStyle eStyle, double fBorder, double fOffsetX, double fOffsetY, double fAngle, const basegfx::BColorStops &rColorStops, sal_uInt16 nSteps)
bool operator==(const ImpFillGradientAttribute &rCandidate) const
const basegfx::BColorStops & getColorStops() const
bool same_object(const cow_wrapper &rOther) const
bool equalZero(const T &rfVal)
bool equal(T const &rfValA, T const &rfValB)
size