Line data Source code
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 : #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
21 : #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
22 :
23 : #include <drawinglayer/drawinglayerdllapi.h>
24 : #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
25 : #include <basegfx/color/bcolor.hxx>
26 : #include <basegfx/polygon/b2dpolypolygon.hxx>
27 : #include <basegfx/matrix/b2dhommatrix.hxx>
28 : #include <drawinglayer/primitive2d/primitivetools2d.hxx>
29 : #include <vector>
30 :
31 :
32 : // SvgGradientEntry class
33 :
34 : namespace drawinglayer
35 : {
36 : namespace primitive2d
37 : {
38 : /// a single GradientStop defining a color and opacity at a distance
39 29195 : class SvgGradientEntry
40 : {
41 : private:
42 : double mfOffset;
43 : basegfx::BColor maColor;
44 : double mfOpacity;
45 :
46 : public:
47 4568 : SvgGradientEntry(double fOffset, const basegfx::BColor& rColor = basegfx::BColor(0.0, 0.0, 0.0), double fOpacity = 1.0)
48 : : mfOffset(fOffset),
49 : maColor(rColor),
50 4568 : mfOpacity(fOpacity)
51 : {
52 4568 : }
53 :
54 26755 : double getOffset() const { return mfOffset; }
55 7885 : const basegfx::BColor& getColor() const { return maColor; }
56 7881 : double getOpacity() const { return mfOpacity; }
57 :
58 0 : bool operator==(const SvgGradientEntry& rCompare) const
59 : {
60 0 : return (getOffset() == rCompare.getOffset()
61 0 : && getColor() == rCompare.getColor()
62 0 : && getOpacity() == rCompare.getOpacity());
63 : }
64 :
65 4138 : bool operator<(const SvgGradientEntry& rCompare) const
66 : {
67 4138 : return getOffset() < rCompare.getOffset();
68 : }
69 : };
70 :
71 : typedef ::std::vector< SvgGradientEntry > SvgGradientEntryVector;
72 :
73 : } // end of namespace primitive2d
74 : } // end of namespace drawinglayer
75 :
76 :
77 : // SvgGradientHelper class
78 :
79 : namespace drawinglayer
80 : {
81 : namespace primitive2d
82 : {
83 : enum SpreadMethod
84 : {
85 : Spread_pad = 0,
86 : Spread_reflect,
87 : Spread_repeat
88 : };
89 :
90 : /* helper for linear and radial gradient, both get derived from this
91 : to share common definitions and functionality
92 : **/
93 : class SvgGradientHelper
94 : {
95 : private:
96 : /// the extra gradient transform
97 : basegfx::B2DHomMatrix maGradientTransform;
98 :
99 : /// geometric definition, the geometry to be filled
100 : basegfx::B2DPolyPolygon maPolyPolygon;
101 :
102 : /// the gradient definition
103 : SvgGradientEntryVector maGradientEntries;
104 :
105 : /// start and/or center point
106 : basegfx::B2DPoint maStart;
107 :
108 : /// how to spread
109 : SpreadMethod maSpreadMethod;
110 :
111 : /// bitfield
112 : bool mbPreconditionsChecked : 1;
113 : bool mbCreatesContent : 1;
114 : bool mbSingleEntry : 1;
115 : bool mbFullyOpaque : 1;
116 :
117 : // true = interpret in unit coordinate system -> object aspect ratio will scale result
118 : // false = interpret in object coordinate system -> object aspect ratio will not scale result
119 : // (related to SVG's gradientUnits (userSpaceOnUse|objectBoundingBox)
120 : bool mbUseUnitCoordinates : 1;
121 :
122 : protected:
123 : /// local helpers
124 : Primitive2DSequence createSingleGradientEntryFill() const;
125 : virtual void createAtom(
126 : Primitive2DVector& rTargetColor,
127 : Primitive2DVector& rTargetOpacity,
128 : const SvgGradientEntry& rFrom,
129 : const SvgGradientEntry& rTo,
130 : sal_Int32 nOffset) const = 0;
131 : double createRun(
132 : Primitive2DVector& rTargetColor,
133 : Primitive2DVector& rTargetOpacity,
134 : double fPos,
135 : double fMax,
136 : const SvgGradientEntryVector& rEntries,
137 : sal_Int32 nOffset) const;
138 : virtual void checkPreconditions();
139 : Primitive2DSequence createResult(
140 : const Primitive2DVector& rTargetColor,
141 : const Primitive2DVector& rTargetOpacity,
142 : const basegfx::B2DHomMatrix& rUnitGradientToObject,
143 : bool bInvert = false) const;
144 2488 : bool getCreatesContent() const { return mbCreatesContent; }
145 1244 : bool getSingleEntry() const { return mbSingleEntry; }
146 0 : void setSingleEntry() { mbSingleEntry = true; }
147 1244 : bool getPreconditionsChecked() const { return mbPreconditionsChecked; }
148 3315 : bool getFullyOpaque() const { return mbFullyOpaque; }
149 :
150 : public:
151 : /// constructor
152 : SvgGradientHelper(
153 : const basegfx::B2DHomMatrix& rGradientTransform,
154 : const basegfx::B2DPolyPolygon& rPolyPolygon,
155 : const SvgGradientEntryVector& rGradientEntries,
156 : const basegfx::B2DPoint& rStart,
157 : bool bUseUnitCoordinates,
158 : SpreadMethod aSpreadMethod = Spread_pad);
159 : virtual ~SvgGradientHelper();
160 :
161 : /// data read access
162 1448 : const basegfx::B2DHomMatrix& getGradientTransform() const { return maGradientTransform; }
163 6839 : const basegfx::B2DPolyPolygon& getPolyPolygon() const { return maPolyPolygon; }
164 2488 : const SvgGradientEntryVector& getGradientEntries() const { return maGradientEntries; }
165 2389 : const basegfx::B2DPoint& getStart() const { return maStart; }
166 1244 : bool getUseUnitCoordinates() const { return mbUseUnitCoordinates; }
167 1149 : SpreadMethod getSpreadMethod() const { return maSpreadMethod; }
168 :
169 : /// compare operator
170 : bool operator==(const SvgGradientHelper& rSvgGradientHelper) const;
171 : };
172 : } // end of namespace primitive2d
173 : } // end of namespace drawinglayer
174 :
175 :
176 : // SvgLinearGradientPrimitive2D class
177 :
178 : namespace drawinglayer
179 : {
180 : namespace primitive2d
181 : {
182 : /// the basic linear gradient primitive
183 : class DRAWINGLAYER_DLLPUBLIC SvgLinearGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
184 : {
185 : private:
186 : /// the end point for linear gradient
187 : basegfx::B2DPoint maEnd;
188 :
189 : protected:
190 : /// local helpers
191 : virtual void createAtom(
192 : Primitive2DVector& rTargetColor,
193 : Primitive2DVector& rTargetOpacity,
194 : const SvgGradientEntry& rFrom,
195 : const SvgGradientEntry& rTo,
196 : sal_Int32 nOffset) const SAL_OVERRIDE;
197 : virtual void checkPreconditions() SAL_OVERRIDE;
198 :
199 : /// local decomposition.
200 : virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
201 :
202 : public:
203 : /// constructor
204 : SvgLinearGradientPrimitive2D(
205 : const basegfx::B2DHomMatrix& rGradientTransform,
206 : const basegfx::B2DPolyPolygon& rPolyPolygon,
207 : const SvgGradientEntryVector& rGradientEntries,
208 : const basegfx::B2DPoint& rStart,
209 : const basegfx::B2DPoint& rEnd,
210 : bool bUseUnitCoordinates,
211 : SpreadMethod aSpreadMethod = Spread_pad);
212 : virtual ~SvgLinearGradientPrimitive2D();
213 :
214 : /// data read access
215 2290 : const basegfx::B2DPoint& getEnd() const { return maEnd; }
216 :
217 : /// compare operator
218 : virtual bool operator==(const BasePrimitive2D& rPrimitive) const SAL_OVERRIDE;
219 :
220 : /// get range
221 : virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
222 :
223 : /// provide unique ID
224 : DeclPrimitive2DIDBlock()
225 : };
226 : } // end of namespace primitive2d
227 : } // end of namespace drawinglayer
228 :
229 :
230 : // SvgRadialGradientPrimitive2D class
231 :
232 : namespace drawinglayer
233 : {
234 : namespace primitive2d
235 : {
236 : /// the basic radial gradient primitive
237 : class DRAWINGLAYER_DLLPUBLIC SvgRadialGradientPrimitive2D : public BufferedDecompositionPrimitive2D, public SvgGradientHelper
238 : {
239 : private:
240 : /// the geometric definition
241 : double mfRadius;
242 :
243 : /// Focal only used when focal is set at all, see constructors
244 : basegfx::B2DPoint maFocal;
245 : basegfx::B2DVector maFocalVector;
246 : double maFocalLength;
247 :
248 : // internal helper for case Spread_reflect
249 : SvgGradientEntryVector maMirroredGradientEntries;
250 :
251 : /// bitfield
252 : bool mbFocalSet : 1;
253 :
254 : /// local helpers
255 : const SvgGradientEntryVector& getMirroredGradientEntries() const;
256 : void createMirroredGradientEntries();
257 :
258 : protected:
259 : /// local helpers
260 : virtual void createAtom(
261 : Primitive2DVector& rTargetColor,
262 : Primitive2DVector& rTargetOpacity,
263 : const SvgGradientEntry& rFrom,
264 : const SvgGradientEntry& rTo,
265 : sal_Int32 nOffset) const SAL_OVERRIDE;
266 : virtual void checkPreconditions() SAL_OVERRIDE;
267 :
268 : /// local decomposition.
269 : virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
270 :
271 : public:
272 : /// constructor
273 : SvgRadialGradientPrimitive2D(
274 : const basegfx::B2DHomMatrix& rGradientTransform,
275 : const basegfx::B2DPolyPolygon& rPolyPolygon,
276 : const SvgGradientEntryVector& rGradientEntries,
277 : const basegfx::B2DPoint& rStart,
278 : double fRadius,
279 : bool bUseUnitCoordinates,
280 : SpreadMethod aSpreadMethod = Spread_pad,
281 : const basegfx::B2DPoint* pFocal = 0);
282 : virtual ~SvgRadialGradientPrimitive2D();
283 :
284 : /// data read access
285 198 : double getRadius() const { return mfRadius; }
286 0 : const basegfx::B2DPoint& getFocal() const { return maFocal; }
287 330 : bool isFocalSet() const { return mbFocalSet; }
288 :
289 : /// compare operator
290 : virtual bool operator==(const BasePrimitive2D& rPrimitive) const SAL_OVERRIDE;
291 :
292 : /// get range
293 : virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
294 :
295 : /// provide unique ID
296 : DeclPrimitive2DIDBlock()
297 : };
298 : } // end of namespace primitive2d
299 : } // end of namespace drawinglayer
300 :
301 :
302 : // SvgLinearAtomPrimitive2D class
303 :
304 : namespace drawinglayer
305 : {
306 : namespace primitive2d
307 : {
308 : /* basic primitive for a single linear GradientRun in unit coordiantes.
309 : It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
310 : decompositions allowing reduced color steps
311 : **/
312 6168 : class DRAWINGLAYER_DLLPUBLIC SvgLinearAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
313 : {
314 : private:
315 : /// the geometric definition in unit coordiantes
316 : basegfx::BColor maColorA;
317 : basegfx::BColor maColorB;
318 : double mfOffsetA;
319 : double mfOffsetB;
320 :
321 : protected:
322 :
323 : /// local decomposition.
324 : virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
325 :
326 : public:
327 : /// constructor
328 : SvgLinearAtomPrimitive2D(
329 : const basegfx::BColor& aColorA, double fOffsetA,
330 : const basegfx::BColor& aColorB, double fOffsetB);
331 :
332 : /// data read access
333 6144 : const basegfx::BColor& getColorA() const { return maColorA; }
334 6144 : const basegfx::BColor& getColorB() const { return maColorB; }
335 18432 : double getOffsetA() const { return mfOffsetA; }
336 6144 : double getOffsetB() const { return mfOffsetB; }
337 :
338 : /// compare operator
339 : virtual bool operator==(const BasePrimitive2D& rPrimitive) const SAL_OVERRIDE;
340 :
341 : /// provide unique ID
342 : DeclPrimitive2DIDBlock()
343 : };
344 : } // end of namespace primitive2d
345 : } // end of namespace drawinglayer
346 :
347 :
348 : // SvgRadialAtomPrimitive2D class
349 :
350 : namespace drawinglayer
351 : {
352 : namespace primitive2d
353 : {
354 : /* basic primitive for a single radial GradientRun in unit coordiantes.
355 : It's derived from DiscreteMetricDependentPrimitive2D to allow view-dependent
356 : decompositions allowing reduced color steps
357 : **/
358 : class DRAWINGLAYER_DLLPUBLIC SvgRadialAtomPrimitive2D : public DiscreteMetricDependentPrimitive2D
359 : {
360 : private:
361 : /// the geometric definition in unit coordiantes
362 : basegfx::BColor maColorA;
363 : basegfx::BColor maColorB;
364 : double mfScaleA;
365 : double mfScaleB;
366 :
367 : // helper to hold translation vectors when given (for focal)
368 0 : struct VectorPair
369 : {
370 : basegfx::B2DVector maTranslateA;
371 : basegfx::B2DVector maTranslateB;
372 :
373 0 : VectorPair(const basegfx::B2DVector& rTranslateA, const basegfx::B2DVector& rTranslateB)
374 : : maTranslateA(rTranslateA),
375 0 : maTranslateB(rTranslateB)
376 : {
377 0 : }
378 : };
379 :
380 : /// Only used when focal is set
381 : VectorPair* mpTranslate;
382 :
383 : protected:
384 :
385 : /// local decomposition.
386 : virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const SAL_OVERRIDE;
387 :
388 : public:
389 : /// constructor
390 : SvgRadialAtomPrimitive2D(
391 : const basegfx::BColor& aColorA, double fScaleA, const basegfx::B2DVector& rTranslateA,
392 : const basegfx::BColor& aColorB, double fScaleB, const basegfx::B2DVector& rTranslateB);
393 : SvgRadialAtomPrimitive2D(
394 : const basegfx::BColor& aColorA, double fScaleA,
395 : const basegfx::BColor& aColorB, double fScaleB);
396 : virtual ~SvgRadialAtomPrimitive2D();
397 :
398 : /// data read access
399 462 : const basegfx::BColor& getColorA() const { return maColorA; }
400 462 : const basegfx::BColor& getColorB() const { return maColorB; }
401 462 : double getScaleA() const { return mfScaleA; }
402 3789 : double getScaleB() const { return mfScaleB; }
403 3327 : bool isTranslateSet() const { return (0 != mpTranslate); }
404 0 : basegfx::B2DVector getTranslateA() const { if(mpTranslate) return mpTranslate->maTranslateA; return basegfx::B2DVector(); }
405 0 : basegfx::B2DVector getTranslateB() const { if(mpTranslate) return mpTranslate->maTranslateB; return basegfx::B2DVector(); }
406 :
407 : /// compare operator
408 : virtual bool operator==(const BasePrimitive2D& rPrimitive) const SAL_OVERRIDE;
409 :
410 : /// provide unique ID
411 : DeclPrimitive2DIDBlock()
412 : };
413 : } // end of namespace primitive2d
414 : } // end of namespace drawinglayer
415 :
416 :
417 :
418 : #endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_SVGGRADIENTPRIMITIVE2D_HXX
419 :
420 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|