1ddde725dSArmin Le Grand /**************************************************************
2ddde725dSArmin Le Grand  *
3ddde725dSArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4ddde725dSArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5ddde725dSArmin Le Grand  * distributed with this work for additional information
6ddde725dSArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7ddde725dSArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8ddde725dSArmin Le Grand  * "License"); you may not use this file except in compliance
9ddde725dSArmin Le Grand  * with the License.  You may obtain a copy of the License at
10ddde725dSArmin Le Grand  *
11ddde725dSArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
12ddde725dSArmin Le Grand  *
13ddde725dSArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14ddde725dSArmin Le Grand  * software distributed under the License is distributed on an
15ddde725dSArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ddde725dSArmin Le Grand  * KIND, either express or implied.  See the License for the
17ddde725dSArmin Le Grand  * specific language governing permissions and limitations
18ddde725dSArmin Le Grand  * under the License.
19ddde725dSArmin Le Grand  *
20ddde725dSArmin Le Grand  *************************************************************/
21ddde725dSArmin Le Grand 
22ddde725dSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23ddde725dSArmin Le Grand #include "precompiled_svgio.hxx"
24ddde725dSArmin Le Grand 
25ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientnode.hxx>
26ddde725dSArmin Le Grand #include <svgio/svgreader/svgdocument.hxx>
27ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientstopnode.hxx>
28ddde725dSArmin Le Grand 
29ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
30ddde725dSArmin Le Grand 
31ddde725dSArmin Le Grand namespace svgio
32ddde725dSArmin Le Grand {
33ddde725dSArmin Le Grand     namespace svgreader
34ddde725dSArmin Le Grand     {
tryToFindLink()35ddde725dSArmin Le Grand         void SvgGradientNode::tryToFindLink()
36ddde725dSArmin Le Grand         {
37ddde725dSArmin Le Grand             if(!mpXLink && maXLink.getLength())
38ddde725dSArmin Le Grand             {
39ddde725dSArmin Le Grand                 mpXLink = dynamic_cast< const SvgGradientNode* >(getDocument().findSvgNodeById(maXLink));
40ddde725dSArmin Le Grand             }
41ddde725dSArmin Le Grand         }
42ddde725dSArmin Le Grand 
SvgGradientNode(SVGToken aType,SvgDocument & rDocument,SvgNode * pParent)43ddde725dSArmin Le Grand         SvgGradientNode::SvgGradientNode(
44ddde725dSArmin Le Grand             SVGToken aType,
45ddde725dSArmin Le Grand             SvgDocument& rDocument,
46ddde725dSArmin Le Grand             SvgNode* pParent)
47ddde725dSArmin Le Grand         :   SvgNode(aType, rDocument, pParent),
48ddde725dSArmin Le Grand             maSvgStyleAttributes(*this),
49ddde725dSArmin Le Grand             maX1(),
50ddde725dSArmin Le Grand             maY1(),
51ddde725dSArmin Le Grand             maX2(),
52ddde725dSArmin Le Grand             maY2(),
53ddde725dSArmin Le Grand             maCx(),
54ddde725dSArmin Le Grand             maCy(),
55ddde725dSArmin Le Grand             maR(),
56ddde725dSArmin Le Grand             maFx(),
57ddde725dSArmin Le Grand             maFy(),
58ddde725dSArmin Le Grand             maGradientUnits(objectBoundingBox),
59ddde725dSArmin Le Grand             maSpreadMethod(drawinglayer::primitive2d::Spread_pad),
60ddde725dSArmin Le Grand             mpaGradientTransform(0),
61ddde725dSArmin Le Grand             maXLink(),
62ddde725dSArmin Le Grand             mpXLink(0)
63ddde725dSArmin Le Grand         {
64*b3ba8dd4SArmin Le Grand             OSL_ENSURE(aType == SVGTokenLinearGradient || aType == SVGTokenRadialGradient, "SvgGradientNode should ony be used for Linear and Radial gradient (!)");
65ddde725dSArmin Le Grand         }
66ddde725dSArmin Le Grand 
~SvgGradientNode()67ddde725dSArmin Le Grand         SvgGradientNode::~SvgGradientNode()
68ddde725dSArmin Le Grand         {
69ddde725dSArmin Le Grand             if(mpaGradientTransform) delete mpaGradientTransform;
70ddde725dSArmin Le Grand             // do NOT delete mpXLink, it's only referenced, not owned
71ddde725dSArmin Le Grand         }
72ddde725dSArmin Le Grand 
getSvgStyleAttributes() const73ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
74ddde725dSArmin Le Grand         {
75ddde725dSArmin Le Grand             return &maSvgStyleAttributes;
76ddde725dSArmin Le Grand         }
77ddde725dSArmin Le Grand 
parseAttribute(const rtl::OUString & rTokenName,SVGToken aSVGToken,const rtl::OUString & aContent)78ddde725dSArmin Le Grand         void SvgGradientNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
79ddde725dSArmin Le Grand         {
80ddde725dSArmin Le Grand             // call parent
81ddde725dSArmin Le Grand             SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
82ddde725dSArmin Le Grand 
83ddde725dSArmin Le Grand             // read style attributes
84ddde725dSArmin Le Grand             maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
85ddde725dSArmin Le Grand 
86ddde725dSArmin Le Grand             // parse own
87ddde725dSArmin Le Grand             switch(aSVGToken)
88ddde725dSArmin Le Grand             {
89ddde725dSArmin Le Grand                 case SVGTokenStyle:
90ddde725dSArmin Le Grand                 {
91ddde725dSArmin Le Grand                     maSvgStyleAttributes.readStyle(aContent);
92ddde725dSArmin Le Grand                     break;
93ddde725dSArmin Le Grand                 }
94ddde725dSArmin Le Grand                 case SVGTokenX1:
95ddde725dSArmin Le Grand                 {
96ddde725dSArmin Le Grand                     SvgNumber aNum;
97ddde725dSArmin Le Grand 
98ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
99ddde725dSArmin Le Grand                     {
100ddde725dSArmin Le Grand                         setX1(aNum);
101ddde725dSArmin Le Grand                     }
102ddde725dSArmin Le Grand                     break;
103ddde725dSArmin Le Grand                 }
104ddde725dSArmin Le Grand                 case SVGTokenY1:
105ddde725dSArmin Le Grand                 {
106ddde725dSArmin Le Grand                     SvgNumber aNum;
107ddde725dSArmin Le Grand 
108ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
109ddde725dSArmin Le Grand                     {
110ddde725dSArmin Le Grand                         setY1(aNum);
111ddde725dSArmin Le Grand                     }
112ddde725dSArmin Le Grand                     break;
113ddde725dSArmin Le Grand                 }
114ddde725dSArmin Le Grand                 case SVGTokenX2:
115ddde725dSArmin Le Grand                 {
116ddde725dSArmin Le Grand                     SvgNumber aNum;
117ddde725dSArmin Le Grand 
118ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
119ddde725dSArmin Le Grand                     {
120ddde725dSArmin Le Grand                         setX2(aNum);
121ddde725dSArmin Le Grand                     }
122ddde725dSArmin Le Grand                     break;
123ddde725dSArmin Le Grand                 }
124ddde725dSArmin Le Grand                 case SVGTokenY2:
125ddde725dSArmin Le Grand                 {
126ddde725dSArmin Le Grand                     SvgNumber aNum;
127ddde725dSArmin Le Grand 
128ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
129ddde725dSArmin Le Grand                     {
130ddde725dSArmin Le Grand                         setY2(aNum);
131ddde725dSArmin Le Grand                     }
132ddde725dSArmin Le Grand                     break;
133ddde725dSArmin Le Grand                 }
134ddde725dSArmin Le Grand                 case SVGTokenCx:
135ddde725dSArmin Le Grand                 {
136ddde725dSArmin Le Grand                     SvgNumber aNum;
137ddde725dSArmin Le Grand 
138ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
139ddde725dSArmin Le Grand                     {
140ddde725dSArmin Le Grand                         setCx(aNum);
141ddde725dSArmin Le Grand                     }
142ddde725dSArmin Le Grand                     break;
143ddde725dSArmin Le Grand                 }
144ddde725dSArmin Le Grand                 case SVGTokenCy:
145ddde725dSArmin Le Grand                 {
146ddde725dSArmin Le Grand                     SvgNumber aNum;
147ddde725dSArmin Le Grand 
148ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
149ddde725dSArmin Le Grand                     {
150ddde725dSArmin Le Grand                         setCy(aNum);
151ddde725dSArmin Le Grand                     }
152ddde725dSArmin Le Grand                     break;
153ddde725dSArmin Le Grand                 }
154ddde725dSArmin Le Grand                 case SVGTokenFx:
155ddde725dSArmin Le Grand                 {
156ddde725dSArmin Le Grand                     SvgNumber aNum;
157ddde725dSArmin Le Grand 
158ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
159ddde725dSArmin Le Grand                     {
160ddde725dSArmin Le Grand                         setFx(aNum);
161ddde725dSArmin Le Grand                     }
162ddde725dSArmin Le Grand                     break;
163ddde725dSArmin Le Grand                 }
164ddde725dSArmin Le Grand                 case SVGTokenFy:
165ddde725dSArmin Le Grand                 {
166ddde725dSArmin Le Grand                     SvgNumber aNum;
167ddde725dSArmin Le Grand 
168ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
169ddde725dSArmin Le Grand                     {
170ddde725dSArmin Le Grand                         setFy(aNum);
171ddde725dSArmin Le Grand                     }
172ddde725dSArmin Le Grand                     break;
173ddde725dSArmin Le Grand                 }
174ddde725dSArmin Le Grand                 case SVGTokenR:
175ddde725dSArmin Le Grand                 {
176ddde725dSArmin Le Grand                     SvgNumber aNum;
177ddde725dSArmin Le Grand 
178ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
179ddde725dSArmin Le Grand                     {
180ddde725dSArmin Le Grand                         if(aNum.isPositive())
181ddde725dSArmin Le Grand                         {
182ddde725dSArmin Le Grand                             setR(aNum);
183ddde725dSArmin Le Grand                         }
184ddde725dSArmin Le Grand                     }
185ddde725dSArmin Le Grand                     break;
186ddde725dSArmin Le Grand                 }
187ddde725dSArmin Le Grand                 case SVGTokenGradientUnits:
188ddde725dSArmin Le Grand                 {
189ddde725dSArmin Le Grand                     if(aContent.getLength())
190ddde725dSArmin Le Grand                     {
191ddde725dSArmin Le Grand                         if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
192ddde725dSArmin Le Grand                         {
193ddde725dSArmin Le Grand                             setGradientUnits(userSpaceOnUse);
194ddde725dSArmin Le Grand                         }
195ddde725dSArmin Le Grand                         else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
196ddde725dSArmin Le Grand                         {
197ddde725dSArmin Le Grand                             setGradientUnits(objectBoundingBox);
198ddde725dSArmin Le Grand                         }
199ddde725dSArmin Le Grand                     }
200ddde725dSArmin Le Grand                     break;
201ddde725dSArmin Le Grand                 }
202ddde725dSArmin Le Grand                 case SVGTokenSpreadMethod:
203ddde725dSArmin Le Grand                 {
204ddde725dSArmin Le Grand                     if(aContent.getLength())
205ddde725dSArmin Le Grand                     {
206ddde725dSArmin Le Grand                         static rtl::OUString aStrPad(rtl::OUString::createFromAscii("pad"));
207ddde725dSArmin Le Grand                         static rtl::OUString aStrReflect(rtl::OUString::createFromAscii("reflect"));
208ddde725dSArmin Le Grand                         static rtl::OUString aStrRepeat(rtl::OUString::createFromAscii("repeat"));
209ddde725dSArmin Le Grand 
210ddde725dSArmin Le Grand                         if(aContent.match(aStrPad, 0))
211ddde725dSArmin Le Grand                         {
212ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
213ddde725dSArmin Le Grand                         }
214ddde725dSArmin Le Grand                         else if(aContent.match(aStrReflect, 0))
215ddde725dSArmin Le Grand                         {
216ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
217ddde725dSArmin Le Grand                         }
218ddde725dSArmin Le Grand                         else if(aContent.match(aStrRepeat, 0))
219ddde725dSArmin Le Grand                         {
220ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_repeat);
221ddde725dSArmin Le Grand                         }
222ddde725dSArmin Le Grand                     }
223ddde725dSArmin Le Grand                     break;
224ddde725dSArmin Le Grand                 }
225ddde725dSArmin Le Grand                 case SVGTokenGradientTransform:
226ddde725dSArmin Le Grand                 {
227ddde725dSArmin Le Grand                     const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
228ddde725dSArmin Le Grand 
229ddde725dSArmin Le Grand                     if(!aMatrix.isIdentity())
230ddde725dSArmin Le Grand                     {
231ddde725dSArmin Le Grand                         setGradientTransform(&aMatrix);
232ddde725dSArmin Le Grand                     }
233ddde725dSArmin Le Grand                     break;
234ddde725dSArmin Le Grand                 }
235ddde725dSArmin Le Grand                 case SVGTokenXlinkHref:
236ddde725dSArmin Le Grand                 {
237ddde725dSArmin Le Grand                     const sal_Int32 nLen(aContent.getLength());
238ddde725dSArmin Le Grand 
239ddde725dSArmin Le Grand                     if(nLen && sal_Unicode('#') == aContent[0])
240ddde725dSArmin Le Grand                     {
241ddde725dSArmin Le Grand                         maXLink = aContent.copy(1);
242ddde725dSArmin Le Grand                         tryToFindLink();
243ddde725dSArmin Le Grand                     }
244ddde725dSArmin Le Grand                     break;
245ddde725dSArmin Le Grand                 }
246e2bf1e9dSArmin Le Grand                 default:
247e2bf1e9dSArmin Le Grand                 {
248e2bf1e9dSArmin Le Grand                     break;
249e2bf1e9dSArmin Le Grand                 }
250ddde725dSArmin Le Grand             }
251ddde725dSArmin Le Grand         }
252ddde725dSArmin Le Grand 
collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector & aVector) const253ddde725dSArmin Le Grand         void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const
254ddde725dSArmin Le Grand         {
255ddde725dSArmin Le Grand             if(getChildren().empty())
256ddde725dSArmin Le Grand             {
257ddde725dSArmin Le Grand                 const_cast< SvgGradientNode* >(this)->tryToFindLink();
258ddde725dSArmin Le Grand 
259ddde725dSArmin Le Grand                 if(mpXLink)
260ddde725dSArmin Le Grand                 {
261ddde725dSArmin Le Grand                     mpXLink->collectGradientEntries(aVector);
262ddde725dSArmin Le Grand                 }
263ddde725dSArmin Le Grand             }
264ddde725dSArmin Le Grand             else
265ddde725dSArmin Le Grand             {
266ddde725dSArmin Le Grand                 const sal_uInt32 nCount(getChildren().size());
267ddde725dSArmin Le Grand 
268ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
269ddde725dSArmin Le Grand                 {
270ddde725dSArmin Le Grand                     const SvgGradientStopNode* pCandidate = dynamic_cast< const SvgGradientStopNode* >(getChildren()[a]);
271ddde725dSArmin Le Grand 
272ddde725dSArmin Le Grand                     if(pCandidate)
273ddde725dSArmin Le Grand                     {
274ddde725dSArmin Le Grand                         const SvgStyleAttributes* pStyle = pCandidate->getSvgStyleAttributes();
275ddde725dSArmin Le Grand 
276ddde725dSArmin Le Grand                         if(pStyle)
277ddde725dSArmin Le Grand                         {
278ddde725dSArmin Le Grand                             const SvgNumber aOffset(pCandidate->getOffset());
279ddde725dSArmin Le Grand                             double fOffset(0.0);
280ddde725dSArmin Le Grand 
281ddde725dSArmin Le Grand                             if(Unit_percent == aOffset.getUnit())
282ddde725dSArmin Le Grand                             {
283ddde725dSArmin Le Grand                                 // percent is not relative to distances in ColorStop context, solve locally
284ddde725dSArmin Le Grand                                 fOffset = aOffset.getNumber() * 0.01;
285ddde725dSArmin Le Grand                             }
286ddde725dSArmin Le Grand                             else
287ddde725dSArmin Le Grand                             {
288ddde725dSArmin Le Grand                                 fOffset = aOffset.solve(*this);
289ddde725dSArmin Le Grand                             }
290ddde725dSArmin Le Grand 
291ddde725dSArmin Le Grand                             if(fOffset < 0.0)
292ddde725dSArmin Le Grand                             {
293ddde725dSArmin Le Grand                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
294ddde725dSArmin Le Grand                                 fOffset = 0.0;
295ddde725dSArmin Le Grand                             }
296ddde725dSArmin Le Grand                             else if(fOffset > 1.0)
297ddde725dSArmin Le Grand                             {
298ddde725dSArmin Le Grand                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
299ddde725dSArmin Le Grand                                 fOffset = 1.0;
300ddde725dSArmin Le Grand                             }
301ddde725dSArmin Le Grand 
302ddde725dSArmin Le Grand                             aVector.push_back(
303ddde725dSArmin Le Grand                                 drawinglayer::primitive2d::SvgGradientEntry(
304ddde725dSArmin Le Grand                                     fOffset,
305ddde725dSArmin Le Grand                                     pStyle->getStopColor(),
306ddde725dSArmin Le Grand                                     pStyle->getStopOpacity().solve(*this)));
307ddde725dSArmin Le Grand                         }
308ddde725dSArmin Le Grand                         else
309ddde725dSArmin Le Grand                         {
310ddde725dSArmin Le Grand                             OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
311ddde725dSArmin Le Grand                         }
312ddde725dSArmin Le Grand                     }
313ddde725dSArmin Le Grand                 }
314ddde725dSArmin Le Grand             }
315ddde725dSArmin Le Grand         }
316ddde725dSArmin Le Grand 
getX1() const317ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getX1() const
318ddde725dSArmin Le Grand         {
319ddde725dSArmin Le Grand             if(maX1.isSet())
320ddde725dSArmin Le Grand             {
321ddde725dSArmin Le Grand                 return maX1;
322ddde725dSArmin Le Grand             }
323ddde725dSArmin Le Grand 
324ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
325ddde725dSArmin Le Grand 
326ddde725dSArmin Le Grand             if(mpXLink)
327ddde725dSArmin Le Grand             {
328ddde725dSArmin Le Grand                 return mpXLink->getX1();
329ddde725dSArmin Le Grand             }
330ddde725dSArmin Le Grand 
331ddde725dSArmin Le Grand             // default is 0%
332ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
333ddde725dSArmin Le Grand         }
334ddde725dSArmin Le Grand 
getY1() const335ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getY1() const
336ddde725dSArmin Le Grand         {
337ddde725dSArmin Le Grand             if(maY1.isSet())
338ddde725dSArmin Le Grand             {
339ddde725dSArmin Le Grand                 return maY1;
340ddde725dSArmin Le Grand             }
341ddde725dSArmin Le Grand 
342ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
343ddde725dSArmin Le Grand 
344ddde725dSArmin Le Grand             if(mpXLink)
345ddde725dSArmin Le Grand             {
346ddde725dSArmin Le Grand                 return mpXLink->getY1();
347ddde725dSArmin Le Grand             }
348ddde725dSArmin Le Grand 
349ddde725dSArmin Le Grand             // default is 0%
350ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
351ddde725dSArmin Le Grand         }
352ddde725dSArmin Le Grand 
getX2() const353ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getX2() const
354ddde725dSArmin Le Grand         {
355ddde725dSArmin Le Grand             if(maX2.isSet())
356ddde725dSArmin Le Grand             {
357ddde725dSArmin Le Grand                 return maX2;
358ddde725dSArmin Le Grand             }
359ddde725dSArmin Le Grand 
360ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
361ddde725dSArmin Le Grand 
362ddde725dSArmin Le Grand             if(mpXLink)
363ddde725dSArmin Le Grand             {
364ddde725dSArmin Le Grand                 return mpXLink->getX2();
365ddde725dSArmin Le Grand             }
366ddde725dSArmin Le Grand 
367ddde725dSArmin Le Grand             // default is 100%
368ddde725dSArmin Le Grand             return SvgNumber(100.0, Unit_percent);
369ddde725dSArmin Le Grand         }
370ddde725dSArmin Le Grand 
getY2() const371ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getY2() const
372ddde725dSArmin Le Grand         {
373ddde725dSArmin Le Grand             if(maY2.isSet())
374ddde725dSArmin Le Grand             {
375ddde725dSArmin Le Grand                 return maY2;
376ddde725dSArmin Le Grand             }
377ddde725dSArmin Le Grand 
378ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
379ddde725dSArmin Le Grand 
380ddde725dSArmin Le Grand             if(mpXLink)
381ddde725dSArmin Le Grand             {
382ddde725dSArmin Le Grand                 return mpXLink->getY2();
383ddde725dSArmin Le Grand             }
384ddde725dSArmin Le Grand 
385ddde725dSArmin Le Grand             // default is 0%
386ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
387ddde725dSArmin Le Grand         }
388ddde725dSArmin Le Grand 
getCx() const389ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getCx() const
390ddde725dSArmin Le Grand         {
391ddde725dSArmin Le Grand             if(maCx.isSet())
392ddde725dSArmin Le Grand             {
393ddde725dSArmin Le Grand                 return maCx;
394ddde725dSArmin Le Grand             }
395ddde725dSArmin Le Grand 
396ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
397ddde725dSArmin Le Grand 
398ddde725dSArmin Le Grand             if(mpXLink)
399ddde725dSArmin Le Grand             {
400ddde725dSArmin Le Grand                 return mpXLink->getCx();
401ddde725dSArmin Le Grand             }
402ddde725dSArmin Le Grand 
403ddde725dSArmin Le Grand             // default is 50%
404ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
405ddde725dSArmin Le Grand         }
406ddde725dSArmin Le Grand 
getCy() const407ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getCy() const
408ddde725dSArmin Le Grand         {
409ddde725dSArmin Le Grand             if(maCy.isSet())
410ddde725dSArmin Le Grand             {
411ddde725dSArmin Le Grand                 return maCy;
412ddde725dSArmin Le Grand             }
413ddde725dSArmin Le Grand 
414ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
415ddde725dSArmin Le Grand 
416ddde725dSArmin Le Grand             if(mpXLink)
417ddde725dSArmin Le Grand             {
418ddde725dSArmin Le Grand                 return mpXLink->getCy();
419ddde725dSArmin Le Grand             }
420ddde725dSArmin Le Grand 
421ddde725dSArmin Le Grand             // default is 50%
422ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
423ddde725dSArmin Le Grand         }
424ddde725dSArmin Le Grand 
getR() const425ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getR() const
426ddde725dSArmin Le Grand         {
427ddde725dSArmin Le Grand             if(maR.isSet())
428ddde725dSArmin Le Grand             {
429ddde725dSArmin Le Grand                 return maR;
430ddde725dSArmin Le Grand             }
431ddde725dSArmin Le Grand 
432ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
433ddde725dSArmin Le Grand 
434ddde725dSArmin Le Grand             if(mpXLink)
435ddde725dSArmin Le Grand             {
436ddde725dSArmin Le Grand                 return mpXLink->getR();
437ddde725dSArmin Le Grand             }
438ddde725dSArmin Le Grand 
439ddde725dSArmin Le Grand             // default is 50%
440ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
441ddde725dSArmin Le Grand         }
442ddde725dSArmin Le Grand 
getFx() const443ddde725dSArmin Le Grand         const SvgNumber* SvgGradientNode::getFx() const
444ddde725dSArmin Le Grand         {
445ddde725dSArmin Le Grand             if(maFx.isSet())
446ddde725dSArmin Le Grand             {
447ddde725dSArmin Le Grand                 return &maFx;
448ddde725dSArmin Le Grand             }
449ddde725dSArmin Le Grand 
450ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
451ddde725dSArmin Le Grand 
452ddde725dSArmin Le Grand             if(mpXLink)
453ddde725dSArmin Le Grand             {
454ddde725dSArmin Le Grand                 return mpXLink->getFx();
455ddde725dSArmin Le Grand             }
456ddde725dSArmin Le Grand 
457ddde725dSArmin Le Grand             return 0;
458ddde725dSArmin Le Grand         }
459ddde725dSArmin Le Grand 
getFy() const460ddde725dSArmin Le Grand         const SvgNumber* SvgGradientNode::getFy() const
461ddde725dSArmin Le Grand         {
462ddde725dSArmin Le Grand             if(maFy.isSet())
463ddde725dSArmin Le Grand             {
464ddde725dSArmin Le Grand                 return &maFy;
465ddde725dSArmin Le Grand             }
466ddde725dSArmin Le Grand 
467ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
468ddde725dSArmin Le Grand 
469ddde725dSArmin Le Grand             if(mpXLink)
470ddde725dSArmin Le Grand             {
471ddde725dSArmin Le Grand                 return mpXLink->getFy();
472ddde725dSArmin Le Grand             }
473ddde725dSArmin Le Grand 
474ddde725dSArmin Le Grand             return 0;
475ddde725dSArmin Le Grand         }
476ddde725dSArmin Le Grand 
getGradientTransform() const477ddde725dSArmin Le Grand         const basegfx::B2DHomMatrix* SvgGradientNode::getGradientTransform() const
478ddde725dSArmin Le Grand         {
479ddde725dSArmin Le Grand             if(mpaGradientTransform)
480ddde725dSArmin Le Grand             {
481ddde725dSArmin Le Grand                 return mpaGradientTransform;
482ddde725dSArmin Le Grand             }
483ddde725dSArmin Le Grand 
484ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
485ddde725dSArmin Le Grand 
486ddde725dSArmin Le Grand             if(mpXLink)
487ddde725dSArmin Le Grand             {
488ddde725dSArmin Le Grand                 return mpXLink->getGradientTransform();
489ddde725dSArmin Le Grand             }
490ddde725dSArmin Le Grand 
491ddde725dSArmin Le Grand             return 0;
492ddde725dSArmin Le Grand         }
493ddde725dSArmin Le Grand 
setGradientTransform(const basegfx::B2DHomMatrix * pMatrix)494ddde725dSArmin Le Grand         void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix* pMatrix)
495ddde725dSArmin Le Grand         {
496ddde725dSArmin Le Grand             if(mpaGradientTransform)
497ddde725dSArmin Le Grand             {
498ddde725dSArmin Le Grand                 delete mpaGradientTransform;
499ddde725dSArmin Le Grand                 mpaGradientTransform = 0;
500ddde725dSArmin Le Grand             }
501ddde725dSArmin Le Grand 
502ddde725dSArmin Le Grand             if(pMatrix)
503ddde725dSArmin Le Grand             {
504ddde725dSArmin Le Grand                 mpaGradientTransform = new basegfx::B2DHomMatrix(*pMatrix);
505ddde725dSArmin Le Grand             }
506ddde725dSArmin Le Grand         }
507ddde725dSArmin Le Grand 
508ddde725dSArmin Le Grand     } // end of namespace svgreader
509ddde725dSArmin Le Grand } // end of namespace svgio
510ddde725dSArmin Le Grand 
511ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
512ddde725dSArmin Le Grand // eof
513