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 .
22 #include <drawinglayer/drawinglayerdllapi.h>
23 #include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx>
24 #include <basegfx/color/bcolor.hxx>
25 #include <basegfx/polygon/b2dpolypolygon.hxx>
26 #include <basegfx/matrix/b2dhommatrix.hxx>
27 #include <drawinglayer/primitive2d/primitivetools2d.hxx>
31 // SvgGradientEntry class
33 namespace drawinglayer::primitive2d
35 /// a single GradientStop defining a color and opacity at a distance
36 class SvgGradientEntry
40 basegfx::BColor maColor
;
44 SvgGradientEntry(double fOffset
, const basegfx::BColor
& rColor
, double fOpacity
)
51 double getOffset() const { return mfOffset
; }
52 const basegfx::BColor
& getColor() const { return maColor
; }
53 double getOpacity() const { return mfOpacity
; }
55 bool operator==(const SvgGradientEntry
& rCompare
) const
57 return (getOffset() == rCompare
.getOffset()
58 && getColor() == rCompare
.getColor()
59 && getOpacity() == rCompare
.getOpacity());
62 bool operator<(const SvgGradientEntry
& rCompare
) const
64 return getOffset() < rCompare
.getOffset();
68 typedef ::std::vector
< SvgGradientEntry
> SvgGradientEntryVector
;
70 // SvgGradientHelper class
72 enum class SpreadMethod
79 /* helper for linear and radial gradient, both get derived from this
80 to share common definitions and functionality
82 class SAL_LOPLUGIN_ANNOTATE("crosscast") SvgGradientHelper
85 /// the extra gradient transform
86 basegfx::B2DHomMatrix maGradientTransform
;
88 /// geometric definition, the geometry to be filled
89 basegfx::B2DPolyPolygon maPolyPolygon
;
91 /// the gradient definition
92 SvgGradientEntryVector maGradientEntries
;
94 // internal helper for case SpreadMethod::Reflect
95 SvgGradientEntryVector maMirroredGradientEntries
;
97 /// start and/or center point
98 basegfx::B2DPoint maStart
;
101 SpreadMethod maSpreadMethod
;
103 bool mbCreatesContent
: 1;
104 bool mbSingleEntry
: 1;
105 bool mbFullyOpaque
: 1;
107 // true = interpret in unit coordinate system -> object aspect ratio will scale result
108 // false = interpret in object coordinate system -> object aspect ratio will not scale result
109 // (related to SVG's gradientUnits (userSpaceOnUse|objectBoundingBox)
110 bool mbUseUnitCoordinates
: 1;
113 const SvgGradientEntryVector
& getMirroredGradientEntries() const;
114 void createMirroredGradientEntries();
115 const SvgGradientEntry
& FindEntryLessOrEqual(sal_Int32
& rInt
, const double fFrac
) const;
116 const SvgGradientEntry
& FindEntryMore(sal_Int32
& rInt
,const double fFrac
) const;
120 Primitive2DReference
createSingleGradientEntryFill() const;
121 virtual void createAtom(
122 Primitive2DContainer
& rTargetColor
,
123 Primitive2DContainer
& rTargetOpacity
,
124 const SvgGradientEntry
& rFrom
,
125 const SvgGradientEntry
& rTo
,
126 sal_Int32 nOffsetFrom
,
127 sal_Int32 nOffsetTo
) const = 0;
129 Primitive2DContainer
& rTargetColor
,
130 Primitive2DContainer
& rTargetOpacity
,
133 virtual void checkPreconditions();
134 Primitive2DReference
createResult(
135 Primitive2DContainer aTargetColor
,
136 Primitive2DContainer aTargetOpacity
,
137 const basegfx::B2DHomMatrix
& rUnitGradientToObject
,
138 bool bInvert
= false) const;
140 void setSingleEntry() { mbSingleEntry
= true; }
141 bool getFullyOpaque() const { return mbFullyOpaque
; }
144 bool getCreatesContent() const { return mbCreatesContent
; }
145 bool getSingleEntry() const { return mbSingleEntry
; }
149 basegfx::B2DHomMatrix aGradientTransform
,
150 basegfx::B2DPolyPolygon aPolyPolygon
,
151 SvgGradientEntryVector
&& rGradientEntries
,
152 const basegfx::B2DPoint
& rStart
,
153 bool bUseUnitCoordinates
,
154 SpreadMethod aSpreadMethod
);
155 virtual ~SvgGradientHelper();
158 const basegfx::B2DHomMatrix
& getGradientTransform() const { return maGradientTransform
; }
159 const basegfx::B2DPolyPolygon
& getPolyPolygon() const { return maPolyPolygon
; }
160 const SvgGradientEntryVector
& getGradientEntries() const { return maGradientEntries
; }
161 const basegfx::B2DPoint
& getStart() const { return maStart
; }
162 bool getUseUnitCoordinates() const { return mbUseUnitCoordinates
; }
163 SpreadMethod
getSpreadMethod() const { return maSpreadMethod
; }
166 bool operator==(const SvgGradientHelper
& rSvgGradientHelper
) const;
168 /// create transformation from UnitGrandient to ObjectTransform
169 virtual basegfx::B2DHomMatrix
createUnitGradientToObjectTransformation() const = 0;
172 /// the basic linear gradient primitive
173 class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D final
: public BufferedDecompositionPrimitive2D
, public SvgGradientHelper
176 /// the end point for linear gradient
177 basegfx::B2DPoint maEnd
;
180 virtual void createAtom(
181 Primitive2DContainer
& rTargetColor
,
182 Primitive2DContainer
& rTargetOpacity
,
183 const SvgGradientEntry
& rFrom
,
184 const SvgGradientEntry
& rTo
,
185 sal_Int32 nOffsetFrom
,
186 sal_Int32 nOffsetTo
) const override
;
187 virtual void checkPreconditions() override
;
189 /// local decomposition.
190 virtual Primitive2DReference
create2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const override
;
194 SvgLinearGradientPrimitive2D(
195 const basegfx::B2DHomMatrix
& rGradientTransform
,
196 const basegfx::B2DPolyPolygon
& rPolyPolygon
,
197 SvgGradientEntryVector
&& rGradientEntries
,
198 const basegfx::B2DPoint
& rStart
,
199 const basegfx::B2DPoint
& rEnd
,
200 bool bUseUnitCoordinates
,
201 SpreadMethod aSpreadMethod
);
202 virtual ~SvgLinearGradientPrimitive2D() override
;
205 const basegfx::B2DPoint
& getEnd() const { return maEnd
; }
208 virtual bool operator==(const BasePrimitive2D
& rPrimitive
) const override
;
211 virtual basegfx::B2DRange
getB2DRange(const geometry::ViewInformation2D
& rViewInformation
) const override
;
213 /// provide unique ID
214 virtual sal_uInt32
getPrimitive2DID() const override
;
216 /// create transformation from UnitGrandient to ObjectTransform
217 virtual basegfx::B2DHomMatrix
createUnitGradientToObjectTransformation() const override
;
220 /// the basic radial gradient primitive
221 class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D final
: public BufferedDecompositionPrimitive2D
, public SvgGradientHelper
224 /// the geometric definition
227 /// Focal only used when focal is set at all, see constructors
228 basegfx::B2DPoint maFocal
;
229 double maFocalLength
;
232 virtual void createAtom(
233 Primitive2DContainer
& rTargetColor
,
234 Primitive2DContainer
& rTargetOpacity
,
235 const SvgGradientEntry
& rFrom
,
236 const SvgGradientEntry
& rTo
,
237 sal_Int32 nOffsetFrom
,
238 sal_Int32 nOffsetTo
) const override
;
239 virtual void checkPreconditions() override
;
241 /// local decomposition.
242 virtual Primitive2DReference
create2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const override
;
246 SvgRadialGradientPrimitive2D(
247 const basegfx::B2DHomMatrix
& rGradientTransform
,
248 const basegfx::B2DPolyPolygon
& rPolyPolygon
,
249 SvgGradientEntryVector
&& rGradientEntries
,
250 const basegfx::B2DPoint
& rStart
,
252 bool bUseUnitCoordinates
,
253 SpreadMethod aSpreadMethod
,
254 const basegfx::B2DPoint
* pFocal
);
255 virtual ~SvgRadialGradientPrimitive2D() override
;
258 double getRadius() const { return mfRadius
; }
259 const basegfx::B2DPoint
& getFocal() const { return maFocal
; }
260 bool isFocalSet() const { return !maFocal
.equal(getStart()); }
263 virtual bool operator==(const BasePrimitive2D
& rPrimitive
) const override
;
266 virtual basegfx::B2DRange
getB2DRange(const geometry::ViewInformation2D
& rViewInformation
) const override
;
268 /// provide unique ID
269 virtual sal_uInt32
getPrimitive2DID() const override
;
271 /// create transformation from UnitGrandient to ObjectTransform
272 virtual basegfx::B2DHomMatrix
createUnitGradientToObjectTransformation() const override
;
275 // SvgLinearAtomPrimitive2D class
277 /* basic primitive for a single linear GradientRun in unit coordinates.
278 It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
279 decompositions allowing reduced color steps
281 class SvgLinearAtomPrimitive2D final
: public DiscreteMetricDependentPrimitive2D
284 /// the geometric definition in unit coordinates
285 basegfx::BColor maColorA
;
286 basegfx::BColor maColorB
;
290 /// local decomposition.
291 virtual Primitive2DReference
create2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const override
;
295 SvgLinearAtomPrimitive2D(
296 const basegfx::BColor
& aColorA
, double fOffsetA
,
297 const basegfx::BColor
& aColorB
, double fOffsetB
);
300 const basegfx::BColor
& getColorA() const { return maColorA
; }
301 const basegfx::BColor
& getColorB() const { return maColorB
; }
302 double getOffsetA() const { return mfOffsetA
; }
303 double getOffsetB() const { return mfOffsetB
; }
306 virtual bool operator==(const BasePrimitive2D
& rPrimitive
) const override
;
308 /// provide unique ID
309 virtual sal_uInt32
getPrimitive2DID() const override
;
312 // SvgRadialAtomPrimitive2D class
314 /* basic primitive for a single radial GradientRun in unit coordinates.
315 It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
316 decompositions allowing reduced color steps
318 class SvgRadialAtomPrimitive2D final
: public DiscreteMetricDependentPrimitive2D
321 /// the geometric definition in unit coordinates
322 basegfx::BColor maColorA
;
323 basegfx::BColor maColorB
;
327 // helper to hold translation vectors when given (for focal)
330 basegfx::B2DVector maTranslateA
;
331 basegfx::B2DVector maTranslateB
;
333 VectorPair(const basegfx::B2DVector
& rTranslateA
, const basegfx::B2DVector
& rTranslateB
)
334 : maTranslateA(rTranslateA
),
335 maTranslateB(rTranslateB
)
340 /// Only used when focal is set
341 std::unique_ptr
<VectorPair
> mpTranslate
;
343 /// local decomposition.
344 virtual Primitive2DReference
create2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const override
;
348 SvgRadialAtomPrimitive2D(
349 const basegfx::BColor
& aColorA
, double fScaleA
, const basegfx::B2DVector
& rTranslateA
,
350 const basegfx::BColor
& aColorB
, double fScaleB
, const basegfx::B2DVector
& rTranslateB
);
351 SvgRadialAtomPrimitive2D(
352 const basegfx::BColor
& aColorA
, double fScaleA
,
353 const basegfx::BColor
& aColorB
, double fScaleB
);
354 virtual ~SvgRadialAtomPrimitive2D() override
;
357 const basegfx::BColor
& getColorA() const { return maColorA
; }
358 const basegfx::BColor
& getColorB() const { return maColorB
; }
359 double getScaleA() const { return mfScaleA
; }
360 double getScaleB() const { return mfScaleB
; }
361 bool isTranslateSet() const { return (nullptr != mpTranslate
); }
362 basegfx::B2DVector
getTranslateA() const { if(mpTranslate
) return mpTranslate
->maTranslateA
; return basegfx::B2DVector(); }
363 basegfx::B2DVector
getTranslateB() const { if(mpTranslate
) return mpTranslate
->maTranslateB
; return basegfx::B2DVector(); }
366 virtual bool operator==(const BasePrimitive2D
& rPrimitive
) const override
;
368 /// provide unique ID
369 virtual sal_uInt32
getPrimitive2DID() const override
;
371 } // end of namespace drawinglayer::primitive2d
374 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */