1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
23 #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
24 
25 #include <drawinglayer/drawinglayerdllapi.h>
26 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
27 #include <basegfx/color/bcolor.hxx>
28 #include <basegfx/polygon/b2dpolypolygon.hxx>
29 #include <basegfx/matrix/b2dhommatrix.hxx>
30 #include <drawinglayer/primitive2d/primitivetools2d.hxx>
31 #include <vector>
32 
33 //////////////////////////////////////////////////////////////////////////////
34 // SvgGradientEntry class
35 
36 namespace drawinglayer
37 {
38     namespace primitive2d
39     {
40         /// a single GradientStop defining a color and opacity at a distance
41         class SvgGradientEntry
42         {
43         private:
44             double              mfOffset;
45             basegfx::BColor     maColor;
46             double              mfOpacity;
47 
48         public:
SvgGradientEntry(double fOffset,const basegfx::BColor & rColor=basegfx::BColor (0.0,0.0,0.0),double fOpacity=1.0)49             SvgGradientEntry(double fOffset, const basegfx::BColor& rColor = basegfx::BColor(0.0, 0.0, 0.0), double fOpacity = 1.0)
50             :   mfOffset(fOffset),
51                 maColor(rColor),
52                 mfOpacity(fOpacity)
53             {
54             }
55 
getOffset() const56             double getOffset() const { return mfOffset; }
getColor() const57             const basegfx::BColor& getColor() const { return maColor; }
getOpacity() const58             double getOpacity() const { return mfOpacity; }
59 
operator ==(const SvgGradientEntry & rCompare) const60             bool operator==(const SvgGradientEntry& rCompare) const
61             {
62                 return (getOffset() == rCompare.getOffset()
63                     && getColor() == getColor()
64                     && getOpacity() == getOpacity());
65             }
66 
operator <(const SvgGradientEntry & rCompare) const67             bool operator<(const SvgGradientEntry& rCompare) const
68             {
69                 return getOffset() < rCompare.getOffset();
70             }
71         };
72 
73         typedef ::std::vector< SvgGradientEntry > SvgGradientEntryVector;
74 
75     } // end of namespace primitive2d
76 } // end of namespace drawinglayer
77 
78 //////////////////////////////////////////////////////////////////////////////
79 // SvgGradientHelper class
80 
81 namespace drawinglayer
82 {
83 	namespace primitive2d
84 	{
85         enum SpreadMethod
86         {
87             Spread_pad = 0,
88             Spread_reflect,
89             Spread_repeat
90         };
91 
92         /*  helper for linear and radial gradient, both get derived from this
93             to share common definitions and functionality
94          **/
95         class SvgGradientHelper
96         {
97         private:
98             /// the extra gradient transform
99             basegfx::B2DHomMatrix       maGradientTransform;
100 
101             /// geometric definition, the geometry to be filled
102             basegfx::B2DPolyPolygon		maPolyPolygon;
103 
104             /// the gradient definition
105             SvgGradientEntryVector      maGradientEntries;
106 
107             /// start and/or center point
108             basegfx::B2DPoint           maStart;
109 
110             /// how to spread
111             SpreadMethod                maSpreadMethod;
112 
113             /// bitfield
114             bool                        mbPreconditionsChecked : 1;
115             bool                        mbCreatesContent : 1;
116             bool                        mbSingleEntry : 1;
117             bool                        mbFullyOpaque : 1;
118 
119             // true = interpret in unit coordinate system -> object aspect ratio will scale result
120             // false = interpret in object coordinate system -> object aspect ratio will not scale result
121             // (related to SVG's gradientUnits (userSpaceOnUse|objectBoundingBox)
122             bool                        mbUseUnitCoordinates : 1;
123 
124         protected:
125             /// local helpers
126             Primitive2DSequence createSingleGradientEntryFill() const;
127             virtual void createAtom(
128                 Primitive2DVector& rTargetColor,
129                 Primitive2DVector& rTargetOpacity,
130                 const SvgGradientEntry& rFrom,
131                 const SvgGradientEntry& rTo,
132                 sal_Int32 nOffset) const = 0;
133             double createRun(
134                 Primitive2DVector& rTargetColor,
135                 Primitive2DVector& rTargetOpacity,
136                 double fPos,
137                 double fMax,
138                 const SvgGradientEntryVector& rEntries,
139                 sal_Int32 nOffset) const;
140             virtual void checkPreconditions();
141             Primitive2DSequence createResult(
142                 const Primitive2DVector& rTargetColor,
143                 const Primitive2DVector& rTargetOpacity,
144                 const basegfx::B2DHomMatrix& rUnitGradientToObject,
145                 bool bInvert = false) const;
getCreatesContent() const146             bool getCreatesContent() const { return mbCreatesContent; }
getSingleEntry() const147             bool getSingleEntry() const { return mbSingleEntry; }
setSingleEntry()148             void setSingleEntry() { mbSingleEntry = true; }
getPreconditionsChecked() const149             bool getPreconditionsChecked() const { return mbPreconditionsChecked; }
getFullyOpaque() const150             bool getFullyOpaque() const { return mbFullyOpaque; }
151 
152         public:
153             /// constructor
154             SvgGradientHelper(
155                 const basegfx::B2DHomMatrix& rGradientTransform,
156                 const basegfx::B2DPolyPolygon& rPolyPolygon,
157                 const SvgGradientEntryVector& rGradientEntries,
158                 const basegfx::B2DPoint& rStart,
159                 bool bUseUnitCoordinates,
160                 SpreadMethod aSpreadMethod = Spread_pad);
161             virtual ~SvgGradientHelper();
162 
163             /// data read access
getGradientTransform() const164             const basegfx::B2DHomMatrix& getGradientTransform() const { return maGradientTransform; }
getPolyPolygon() const165             const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
getGradientEntries() const166             const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; }
getStart() const167             const basegfx::B2DPoint& getStart() const { return maStart; }
getUseUnitCoordinates() const168             bool getUseUnitCoordinates() const { return mbUseUnitCoordinates; }
getSpreadMethod() const169             SpreadMethod getSpreadMethod() const { return maSpreadMethod; }
170 
171             /// compare operator
172             bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
173         };
174     } // end of namespace primitive2d
175 } // end of namespace drawinglayer
176 
177 //////////////////////////////////////////////////////////////////////////////
178 // SvgLinearGradientPrimitive2D class
179 
180 namespace drawinglayer
181 {
182     namespace primitive2d
183     {
184         /// the basic linear gradient primitive
185         class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
186         {
187         private:
188             /// the end point for linear gradient
189             basegfx::B2DPoint                       maEnd;
190 
191         protected:
192             /// local helpers
193             virtual void createAtom(
194                 Primitive2DVector& rTargetColor,
195                 Primitive2DVector& rTargetOpacity,
196                 const SvgGradientEntry& rFrom,
197                 const SvgGradientEntry& rTo,
198                 sal_Int32 nOffset) const;
199             virtual void checkPreconditions();
200 
201             /// local decomposition.
202             virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
203 
204         public:
205             /// constructor
206             SvgLinearGradientPrimitive2D(
207                 const basegfx::B2DHomMatrix& rGradientTransform,
208                 const basegfx::B2DPolyPolygon& rPolyPolygon,
209                 const SvgGradientEntryVector& rGradientEntries,
210                 const basegfx::B2DPoint& rStart,
211                 const basegfx::B2DPoint& rEnd,
212                 bool bUseUnitCoordinates,
213                 SpreadMethod aSpreadMethod = Spread_pad);
214             virtual ~SvgLinearGradientPrimitive2D();
215 
216             /// data read access
getEnd() const217             const basegfx::B2DPoint& getEnd() const { return maEnd; }
218 
219             /// compare operator
220             virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
221 
222             /// get range
223             virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
224 
225             /// provide unique ID
226             DeclPrimitrive2DIDBlock()
227         };
228     } // end of namespace primitive2d
229 } // end of namespace drawinglayer
230 
231 //////////////////////////////////////////////////////////////////////////////
232 // SvgRadialGradientPrimitive2D class
233 
234 namespace drawinglayer
235 {
236     namespace primitive2d
237     {
238         /// the basic radial gradient primitive
239         class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
240         {
241         private:
242             /// the geometric definition
243             double                                  mfRadius;
244 
245             /// Focal only used when focal is set at all, see constructors
246             basegfx::B2DPoint                       maFocal;
247             basegfx::B2DVector                      maFocalVector;
248             double                                  maFocalLength;
249 
250             // internal helper for case Spread_reflect
251             SvgGradientEntryVector                  maMirroredGradientEntries;
252 
253             /// bitfield
254             bool                                    mbFocalSet : 1;
255 
256             /// local helpers
257             const SvgGradientEntryVector& getMirroredGradientEntries() const;
258             void createMirroredGradientEntries();
259 
260         protected:
261             /// local helpers
262             virtual void createAtom(
263                 Primitive2DVector& rTargetColor,
264                 Primitive2DVector& rTargetOpacity,
265                 const SvgGradientEntry& rFrom,
266                 const SvgGradientEntry& rTo,
267                 sal_Int32 nOffset) const;
268             virtual void checkPreconditions();
269 
270             /// local decomposition.
271             virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
272 
273         public:
274             /// constructor
275             SvgRadialGradientPrimitive2D(
276                 const basegfx::B2DHomMatrix& rGradientTransform,
277                 const basegfx::B2DPolyPolygon& rPolyPolygon,
278                 const SvgGradientEntryVector& rGradientEntries,
279                 const basegfx::B2DPoint& rStart,
280                 double fRadius,
281                 bool bUseUnitCoordinates,
282                 SpreadMethod aSpreadMethod = Spread_pad,
283                 const basegfx::B2DPoint* pFocal = 0);
284             virtual ~SvgRadialGradientPrimitive2D();
285 
286             /// data read access
getRadius() const287             double getRadius() const { return mfRadius; }
getFocal() const288             const basegfx::B2DPoint& getFocal() const { return maFocal; }
isFocalSet() const289             bool isFocalSet() const { return mbFocalSet; }
290 
291             /// compare operator
292             virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
293 
294             /// get range
295             virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
296 
297             /// provide unique ID
298             DeclPrimitrive2DIDBlock()
299         };
300     } // end of namespace primitive2d
301 } // end of namespace drawinglayer
302 
303 //////////////////////////////////////////////////////////////////////////////
304 // SvgLinearAtomPrimitive2D class
305 
306 namespace drawinglayer
307 {
308     namespace primitive2d
309     {
310         /*  basic primitive for a single linear GradientRun in unit coordiantes.
311             It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
312             decompositions allowing reduced color steps
313          **/
314         class DRAWINGLAYER_DLLPUBLIC SvgLinearAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
315         {
316         private:
317             /// the geometric definition in unit coordiantes
318             basegfx::BColor             maColorA;
319             basegfx::BColor             maColorB;
320             double                      mfOffsetA;
321             double                      mfOffsetB;
322 
323         protected:
324 
325             /// local decomposition.
326             virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
327 
328         public:
329             /// constructor
330             SvgLinearAtomPrimitive2D(
331                 const basegfx::BColor& aColorA, double fOffsetA,
332                 const basegfx::BColor& aColorB, double fOffsetB);
333 
334             /// data read access
getColorA() const335             const basegfx::BColor& getColorA() const { return maColorA; }
getColorB() const336             const basegfx::BColor& getColorB() const { return maColorB; }
getOffsetA() const337             double getOffsetA() const { return mfOffsetA; }
getOffsetB() const338             double getOffsetB() const { return mfOffsetB; }
339 
340             /// compare operator
341             virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
342 
343             /// provide unique ID
344             DeclPrimitrive2DIDBlock()
345         };
346     } // end of namespace primitive2d
347 } // end of namespace drawinglayer
348 
349 //////////////////////////////////////////////////////////////////////////////
350 // SvgRadialAtomPrimitive2D class
351 
352 namespace drawinglayer
353 {
354     namespace primitive2d
355     {
356         /*  basic primitive for a single radial GradientRun in unit coordiantes.
357             It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
358             decompositions allowing reduced color steps
359          **/
360         class DRAWINGLAYER_DLLPUBLIC SvgRadialAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
361         {
362         private:
363             /// the geometric definition in unit coordiantes
364             basegfx::BColor             maColorA;
365             basegfx::BColor             maColorB;
366             double                      mfScaleA;
367             double                      mfScaleB;
368 
369             // helper to hold translation vectors when given (for focal)
370             struct VectorPair
371             {
372                 basegfx::B2DVector          maTranslateA;
373                 basegfx::B2DVector          maTranslateB;
374 
VectorPairdrawinglayer::primitive2d::SvgRadialAtomPrimitive2D::VectorPair375                 VectorPair(const basegfx::B2DVector& rTranslateA, const basegfx::B2DVector& rTranslateB)
376                 :   maTranslateA(rTranslateA),
377                     maTranslateB(rTranslateB)
378                 {
379                 }
380             };
381 
382             /// Only used when focal is set
383             VectorPair*                 mpTranslate;
384 
385         protected:
386 
387             /// local decomposition.
388             virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
389 
390         public:
391             /// constructor
392             SvgRadialAtomPrimitive2D(
393                 const basegfx::BColor& aColorA, double fScaleA, const basegfx::B2DVector& rTranslateA,
394                 const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB);
395             SvgRadialAtomPrimitive2D(
396                 const basegfx::BColor& aColorA, double fScaleA,
397                 const basegfx::BColor& aColorB, double fScaleB);
398             virtual ~SvgRadialAtomPrimitive2D();
399 
400             /// data read access
getColorA() const401             const basegfx::BColor& getColorA() const { return maColorA; }
getColorB() const402             const basegfx::BColor& getColorB() const { return maColorB; }
getScaleA() const403             double getScaleA() const { return mfScaleA; }
getScaleB() const404             double getScaleB() const { return mfScaleB; }
isTranslateSet() const405             bool isTranslateSet() const { return (0 != mpTranslate); }
getTranslateA() const406             basegfx::B2DVector getTranslateA() const { if(mpTranslate) return mpTranslate->maTranslateA; return basegfx::B2DVector(); }
getTranslateB() const407             basegfx::B2DVector getTranslateB() const { if(mpTranslate) return mpTranslate->maTranslateB; return basegfx::B2DVector(); }
408 
409             /// compare operator
410             virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
411 
412             /// provide unique ID
413             DeclPrimitrive2DIDBlock()
414         };
415     } // end of namespace primitive2d
416 } // end of namespace drawinglayer
417 
418 //////////////////////////////////////////////////////////////////////////////
419 
420 #endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
421 
422 //////////////////////////////////////////////////////////////////////////////
423 // eof
424