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     {
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 
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         {
64ddde725dSArmin Le Grand         }
65ddde725dSArmin Le Grand 
66ddde725dSArmin Le Grand         SvgGradientNode::~SvgGradientNode()
67ddde725dSArmin Le Grand         {
68ddde725dSArmin Le Grand             if(mpaGradientTransform) delete mpaGradientTransform;
69ddde725dSArmin Le Grand             // do NOT delete mpXLink, it's only referenced, not owned
70ddde725dSArmin Le Grand         }
71ddde725dSArmin Le Grand 
72ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
73ddde725dSArmin Le Grand         {
74ddde725dSArmin Le Grand             return &maSvgStyleAttributes;
75ddde725dSArmin Le Grand         }
76ddde725dSArmin Le Grand 
77ddde725dSArmin Le Grand         void SvgGradientNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
78ddde725dSArmin Le Grand         {
79ddde725dSArmin Le Grand             // call parent
80ddde725dSArmin Le Grand             SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
81ddde725dSArmin Le Grand 
82ddde725dSArmin Le Grand             // read style attributes
83ddde725dSArmin Le Grand             maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
84ddde725dSArmin Le Grand 
85ddde725dSArmin Le Grand             // parse own
86ddde725dSArmin Le Grand             switch(aSVGToken)
87ddde725dSArmin Le Grand             {
88ddde725dSArmin Le Grand                 case SVGTokenStyle:
89ddde725dSArmin Le Grand                 {
90ddde725dSArmin Le Grand                     maSvgStyleAttributes.readStyle(aContent);
91ddde725dSArmin Le Grand                     break;
92ddde725dSArmin Le Grand                 }
93ddde725dSArmin Le Grand                 case SVGTokenX1:
94ddde725dSArmin Le Grand                 {
95ddde725dSArmin Le Grand                     SvgNumber aNum;
96ddde725dSArmin Le Grand 
97ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
98ddde725dSArmin Le Grand                     {
99ddde725dSArmin Le Grand                         setX1(aNum);
100ddde725dSArmin Le Grand                     }
101ddde725dSArmin Le Grand                     break;
102ddde725dSArmin Le Grand                 }
103ddde725dSArmin Le Grand                 case SVGTokenY1:
104ddde725dSArmin Le Grand                 {
105ddde725dSArmin Le Grand                     SvgNumber aNum;
106ddde725dSArmin Le Grand 
107ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
108ddde725dSArmin Le Grand                     {
109ddde725dSArmin Le Grand                         setY1(aNum);
110ddde725dSArmin Le Grand                     }
111ddde725dSArmin Le Grand                     break;
112ddde725dSArmin Le Grand                 }
113ddde725dSArmin Le Grand                 case SVGTokenX2:
114ddde725dSArmin Le Grand                 {
115ddde725dSArmin Le Grand                     SvgNumber aNum;
116ddde725dSArmin Le Grand 
117ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
118ddde725dSArmin Le Grand                     {
119ddde725dSArmin Le Grand                         setX2(aNum);
120ddde725dSArmin Le Grand                     }
121ddde725dSArmin Le Grand                     break;
122ddde725dSArmin Le Grand                 }
123ddde725dSArmin Le Grand                 case SVGTokenY2:
124ddde725dSArmin Le Grand                 {
125ddde725dSArmin Le Grand                     SvgNumber aNum;
126ddde725dSArmin Le Grand 
127ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
128ddde725dSArmin Le Grand                     {
129ddde725dSArmin Le Grand                         setY2(aNum);
130ddde725dSArmin Le Grand                     }
131ddde725dSArmin Le Grand                     break;
132ddde725dSArmin Le Grand                 }
133ddde725dSArmin Le Grand                 case SVGTokenCx:
134ddde725dSArmin Le Grand                 {
135ddde725dSArmin Le Grand                     SvgNumber aNum;
136ddde725dSArmin Le Grand 
137ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
138ddde725dSArmin Le Grand                     {
139ddde725dSArmin Le Grand                         setCx(aNum);
140ddde725dSArmin Le Grand                     }
141ddde725dSArmin Le Grand                     break;
142ddde725dSArmin Le Grand                 }
143ddde725dSArmin Le Grand                 case SVGTokenCy:
144ddde725dSArmin Le Grand                 {
145ddde725dSArmin Le Grand                     SvgNumber aNum;
146ddde725dSArmin Le Grand 
147ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
148ddde725dSArmin Le Grand                     {
149ddde725dSArmin Le Grand                         setCy(aNum);
150ddde725dSArmin Le Grand                     }
151ddde725dSArmin Le Grand                     break;
152ddde725dSArmin Le Grand                 }
153ddde725dSArmin Le Grand                 case SVGTokenFx:
154ddde725dSArmin Le Grand                 {
155ddde725dSArmin Le Grand                     SvgNumber aNum;
156ddde725dSArmin Le Grand 
157ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
158ddde725dSArmin Le Grand                     {
159ddde725dSArmin Le Grand                         setFx(aNum);
160ddde725dSArmin Le Grand                     }
161ddde725dSArmin Le Grand                     break;
162ddde725dSArmin Le Grand                 }
163ddde725dSArmin Le Grand                 case SVGTokenFy:
164ddde725dSArmin Le Grand                 {
165ddde725dSArmin Le Grand                     SvgNumber aNum;
166ddde725dSArmin Le Grand 
167ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
168ddde725dSArmin Le Grand                     {
169ddde725dSArmin Le Grand                         setFy(aNum);
170ddde725dSArmin Le Grand                     }
171ddde725dSArmin Le Grand                     break;
172ddde725dSArmin Le Grand                 }
173ddde725dSArmin Le Grand                 case SVGTokenR:
174ddde725dSArmin Le Grand                 {
175ddde725dSArmin Le Grand                     SvgNumber aNum;
176ddde725dSArmin Le Grand 
177ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
178ddde725dSArmin Le Grand                     {
179ddde725dSArmin Le Grand                         if(aNum.isPositive())
180ddde725dSArmin Le Grand                         {
181ddde725dSArmin Le Grand                             setR(aNum);
182ddde725dSArmin Le Grand                         }
183ddde725dSArmin Le Grand                     }
184ddde725dSArmin Le Grand                     break;
185ddde725dSArmin Le Grand                 }
186ddde725dSArmin Le Grand                 case SVGTokenGradientUnits:
187ddde725dSArmin Le Grand                 {
188ddde725dSArmin Le Grand                     if(aContent.getLength())
189ddde725dSArmin Le Grand                     {
190ddde725dSArmin Le Grand                         if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
191ddde725dSArmin Le Grand                         {
192ddde725dSArmin Le Grand                             setGradientUnits(userSpaceOnUse);
193ddde725dSArmin Le Grand                         }
194ddde725dSArmin Le Grand                         else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
195ddde725dSArmin Le Grand                         {
196ddde725dSArmin Le Grand                             setGradientUnits(objectBoundingBox);
197ddde725dSArmin Le Grand                         }
198ddde725dSArmin Le Grand                     }
199ddde725dSArmin Le Grand                     break;
200ddde725dSArmin Le Grand                 }
201ddde725dSArmin Le Grand                 case SVGTokenSpreadMethod:
202ddde725dSArmin Le Grand                 {
203ddde725dSArmin Le Grand                     if(aContent.getLength())
204ddde725dSArmin Le Grand                     {
205ddde725dSArmin Le Grand                         static rtl::OUString aStrPad(rtl::OUString::createFromAscii("pad"));
206ddde725dSArmin Le Grand                         static rtl::OUString aStrReflect(rtl::OUString::createFromAscii("reflect"));
207ddde725dSArmin Le Grand                         static rtl::OUString aStrRepeat(rtl::OUString::createFromAscii("repeat"));
208ddde725dSArmin Le Grand 
209ddde725dSArmin Le Grand                         if(aContent.match(aStrPad, 0))
210ddde725dSArmin Le Grand                         {
211ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
212ddde725dSArmin Le Grand                         }
213ddde725dSArmin Le Grand                         else if(aContent.match(aStrReflect, 0))
214ddde725dSArmin Le Grand                         {
215ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
216ddde725dSArmin Le Grand                         }
217ddde725dSArmin Le Grand                         else if(aContent.match(aStrRepeat, 0))
218ddde725dSArmin Le Grand                         {
219ddde725dSArmin Le Grand                             setSpreadMethod(drawinglayer::primitive2d::Spread_repeat);
220ddde725dSArmin Le Grand                         }
221ddde725dSArmin Le Grand                     }
222ddde725dSArmin Le Grand                     break;
223ddde725dSArmin Le Grand                 }
224ddde725dSArmin Le Grand                 case SVGTokenGradientTransform:
225ddde725dSArmin Le Grand                 {
226ddde725dSArmin Le Grand                     const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
227ddde725dSArmin Le Grand 
228ddde725dSArmin Le Grand                     if(!aMatrix.isIdentity())
229ddde725dSArmin Le Grand                     {
230ddde725dSArmin Le Grand                         setGradientTransform(&aMatrix);
231ddde725dSArmin Le Grand                     }
232ddde725dSArmin Le Grand                     break;
233ddde725dSArmin Le Grand                 }
234ddde725dSArmin Le Grand                 case SVGTokenXlinkHref:
235ddde725dSArmin Le Grand                 {
236ddde725dSArmin Le Grand                     const sal_Int32 nLen(aContent.getLength());
237ddde725dSArmin Le Grand 
238ddde725dSArmin Le Grand                     if(nLen && sal_Unicode('#') == aContent[0])
239ddde725dSArmin Le Grand                     {
240ddde725dSArmin Le Grand                         maXLink = aContent.copy(1);
241ddde725dSArmin Le Grand                         tryToFindLink();
242ddde725dSArmin Le Grand                     }
243ddde725dSArmin Le Grand                     break;
244ddde725dSArmin Le Grand                 }
245*e2bf1e9dSArmin Le Grand                 default:
246*e2bf1e9dSArmin Le Grand                 {
247*e2bf1e9dSArmin Le Grand                     break;
248*e2bf1e9dSArmin Le Grand                 }
249ddde725dSArmin Le Grand             }
250ddde725dSArmin Le Grand         }
251ddde725dSArmin Le Grand 
252ddde725dSArmin Le Grand         void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const
253ddde725dSArmin Le Grand         {
254ddde725dSArmin Le Grand             if(getChildren().empty())
255ddde725dSArmin Le Grand             {
256ddde725dSArmin Le Grand                 const_cast< SvgGradientNode* >(this)->tryToFindLink();
257ddde725dSArmin Le Grand 
258ddde725dSArmin Le Grand                 if(mpXLink)
259ddde725dSArmin Le Grand                 {
260ddde725dSArmin Le Grand                     mpXLink->collectGradientEntries(aVector);
261ddde725dSArmin Le Grand                 }
262ddde725dSArmin Le Grand             }
263ddde725dSArmin Le Grand             else
264ddde725dSArmin Le Grand             {
265ddde725dSArmin Le Grand                 const sal_uInt32 nCount(getChildren().size());
266ddde725dSArmin Le Grand 
267ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
268ddde725dSArmin Le Grand                 {
269ddde725dSArmin Le Grand                     const SvgGradientStopNode* pCandidate = dynamic_cast< const SvgGradientStopNode* >(getChildren()[a]);
270ddde725dSArmin Le Grand 
271ddde725dSArmin Le Grand                     if(pCandidate)
272ddde725dSArmin Le Grand                     {
273ddde725dSArmin Le Grand                         const SvgStyleAttributes* pStyle = pCandidate->getSvgStyleAttributes();
274ddde725dSArmin Le Grand 
275ddde725dSArmin Le Grand                         if(pStyle)
276ddde725dSArmin Le Grand                         {
277ddde725dSArmin Le Grand                             const SvgNumber aOffset(pCandidate->getOffset());
278ddde725dSArmin Le Grand                             double fOffset(0.0);
279ddde725dSArmin Le Grand 
280ddde725dSArmin Le Grand                             if(Unit_percent == aOffset.getUnit())
281ddde725dSArmin Le Grand                             {
282ddde725dSArmin Le Grand                                 // percent is not relative to distances in ColorStop context, solve locally
283ddde725dSArmin Le Grand                                 fOffset = aOffset.getNumber() * 0.01;
284ddde725dSArmin Le Grand                             }
285ddde725dSArmin Le Grand                             else
286ddde725dSArmin Le Grand                             {
287ddde725dSArmin Le Grand                                 fOffset = aOffset.solve(*this);
288ddde725dSArmin Le Grand                             }
289ddde725dSArmin Le Grand 
290ddde725dSArmin Le Grand                             if(fOffset < 0.0)
291ddde725dSArmin Le Grand                             {
292ddde725dSArmin Le Grand                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
293ddde725dSArmin Le Grand                                 fOffset = 0.0;
294ddde725dSArmin Le Grand                             }
295ddde725dSArmin Le Grand                             else if(fOffset > 1.0)
296ddde725dSArmin Le Grand                             {
297ddde725dSArmin Le Grand                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
298ddde725dSArmin Le Grand                                 fOffset = 1.0;
299ddde725dSArmin Le Grand                             }
300ddde725dSArmin Le Grand 
301ddde725dSArmin Le Grand                             aVector.push_back(
302ddde725dSArmin Le Grand                                 drawinglayer::primitive2d::SvgGradientEntry(
303ddde725dSArmin Le Grand                                     fOffset,
304ddde725dSArmin Le Grand                                     pStyle->getStopColor(),
305ddde725dSArmin Le Grand                                     pStyle->getStopOpacity().solve(*this)));
306ddde725dSArmin Le Grand                         }
307ddde725dSArmin Le Grand                         else
308ddde725dSArmin Le Grand                         {
309ddde725dSArmin Le Grand                             OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
310ddde725dSArmin Le Grand                         }
311ddde725dSArmin Le Grand                     }
312ddde725dSArmin Le Grand                 }
313ddde725dSArmin Le Grand             }
314ddde725dSArmin Le Grand         }
315ddde725dSArmin Le Grand 
316ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getX1() const
317ddde725dSArmin Le Grand         {
318ddde725dSArmin Le Grand             if(maX1.isSet())
319ddde725dSArmin Le Grand             {
320ddde725dSArmin Le Grand                 return maX1;
321ddde725dSArmin Le Grand             }
322ddde725dSArmin Le Grand 
323ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
324ddde725dSArmin Le Grand 
325ddde725dSArmin Le Grand             if(mpXLink)
326ddde725dSArmin Le Grand             {
327ddde725dSArmin Le Grand                 return mpXLink->getX1();
328ddde725dSArmin Le Grand             }
329ddde725dSArmin Le Grand 
330ddde725dSArmin Le Grand             // default is 0%
331ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
332ddde725dSArmin Le Grand         }
333ddde725dSArmin Le Grand 
334ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getY1() const
335ddde725dSArmin Le Grand         {
336ddde725dSArmin Le Grand             if(maY1.isSet())
337ddde725dSArmin Le Grand             {
338ddde725dSArmin Le Grand                 return maY1;
339ddde725dSArmin Le Grand             }
340ddde725dSArmin Le Grand 
341ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
342ddde725dSArmin Le Grand 
343ddde725dSArmin Le Grand             if(mpXLink)
344ddde725dSArmin Le Grand             {
345ddde725dSArmin Le Grand                 return mpXLink->getY1();
346ddde725dSArmin Le Grand             }
347ddde725dSArmin Le Grand 
348ddde725dSArmin Le Grand             // default is 0%
349ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
350ddde725dSArmin Le Grand         }
351ddde725dSArmin Le Grand 
352ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getX2() const
353ddde725dSArmin Le Grand         {
354ddde725dSArmin Le Grand             if(maX2.isSet())
355ddde725dSArmin Le Grand             {
356ddde725dSArmin Le Grand                 return maX2;
357ddde725dSArmin Le Grand             }
358ddde725dSArmin Le Grand 
359ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
360ddde725dSArmin Le Grand 
361ddde725dSArmin Le Grand             if(mpXLink)
362ddde725dSArmin Le Grand             {
363ddde725dSArmin Le Grand                 return mpXLink->getX2();
364ddde725dSArmin Le Grand             }
365ddde725dSArmin Le Grand 
366ddde725dSArmin Le Grand             // default is 100%
367ddde725dSArmin Le Grand             return SvgNumber(100.0, Unit_percent);
368ddde725dSArmin Le Grand         }
369ddde725dSArmin Le Grand 
370ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getY2() const
371ddde725dSArmin Le Grand         {
372ddde725dSArmin Le Grand             if(maY2.isSet())
373ddde725dSArmin Le Grand             {
374ddde725dSArmin Le Grand                 return maY2;
375ddde725dSArmin Le Grand             }
376ddde725dSArmin Le Grand 
377ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
378ddde725dSArmin Le Grand 
379ddde725dSArmin Le Grand             if(mpXLink)
380ddde725dSArmin Le Grand             {
381ddde725dSArmin Le Grand                 return mpXLink->getY2();
382ddde725dSArmin Le Grand             }
383ddde725dSArmin Le Grand 
384ddde725dSArmin Le Grand             // default is 0%
385ddde725dSArmin Le Grand             return SvgNumber(0.0, Unit_percent);
386ddde725dSArmin Le Grand         }
387ddde725dSArmin Le Grand 
388ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getCx() const
389ddde725dSArmin Le Grand         {
390ddde725dSArmin Le Grand             if(maCx.isSet())
391ddde725dSArmin Le Grand             {
392ddde725dSArmin Le Grand                 return maCx;
393ddde725dSArmin Le Grand             }
394ddde725dSArmin Le Grand 
395ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
396ddde725dSArmin Le Grand 
397ddde725dSArmin Le Grand             if(mpXLink)
398ddde725dSArmin Le Grand             {
399ddde725dSArmin Le Grand                 return mpXLink->getCx();
400ddde725dSArmin Le Grand             }
401ddde725dSArmin Le Grand 
402ddde725dSArmin Le Grand             // default is 50%
403ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
404ddde725dSArmin Le Grand         }
405ddde725dSArmin Le Grand 
406ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getCy() const
407ddde725dSArmin Le Grand         {
408ddde725dSArmin Le Grand             if(maCy.isSet())
409ddde725dSArmin Le Grand             {
410ddde725dSArmin Le Grand                 return maCy;
411ddde725dSArmin Le Grand             }
412ddde725dSArmin Le Grand 
413ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
414ddde725dSArmin Le Grand 
415ddde725dSArmin Le Grand             if(mpXLink)
416ddde725dSArmin Le Grand             {
417ddde725dSArmin Le Grand                 return mpXLink->getCy();
418ddde725dSArmin Le Grand             }
419ddde725dSArmin Le Grand 
420ddde725dSArmin Le Grand             // default is 50%
421ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
422ddde725dSArmin Le Grand         }
423ddde725dSArmin Le Grand 
424ddde725dSArmin Le Grand         const SvgNumber SvgGradientNode::getR() const
425ddde725dSArmin Le Grand         {
426ddde725dSArmin Le Grand             if(maR.isSet())
427ddde725dSArmin Le Grand             {
428ddde725dSArmin Le Grand                 return maR;
429ddde725dSArmin Le Grand             }
430ddde725dSArmin Le Grand 
431ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
432ddde725dSArmin Le Grand 
433ddde725dSArmin Le Grand             if(mpXLink)
434ddde725dSArmin Le Grand             {
435ddde725dSArmin Le Grand                 return mpXLink->getR();
436ddde725dSArmin Le Grand             }
437ddde725dSArmin Le Grand 
438ddde725dSArmin Le Grand             // default is 50%
439ddde725dSArmin Le Grand             return SvgNumber(50.0, Unit_percent);
440ddde725dSArmin Le Grand         }
441ddde725dSArmin Le Grand 
442ddde725dSArmin Le Grand         const SvgNumber* SvgGradientNode::getFx() const
443ddde725dSArmin Le Grand         {
444ddde725dSArmin Le Grand             if(maFx.isSet())
445ddde725dSArmin Le Grand             {
446ddde725dSArmin Le Grand                 return &maFx;
447ddde725dSArmin Le Grand             }
448ddde725dSArmin Le Grand 
449ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
450ddde725dSArmin Le Grand 
451ddde725dSArmin Le Grand             if(mpXLink)
452ddde725dSArmin Le Grand             {
453ddde725dSArmin Le Grand                 return mpXLink->getFx();
454ddde725dSArmin Le Grand             }
455ddde725dSArmin Le Grand 
456ddde725dSArmin Le Grand             return 0;
457ddde725dSArmin Le Grand         }
458ddde725dSArmin Le Grand 
459ddde725dSArmin Le Grand         const SvgNumber* SvgGradientNode::getFy() const
460ddde725dSArmin Le Grand         {
461ddde725dSArmin Le Grand             if(maFy.isSet())
462ddde725dSArmin Le Grand             {
463ddde725dSArmin Le Grand                 return &maFy;
464ddde725dSArmin Le Grand             }
465ddde725dSArmin Le Grand 
466ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
467ddde725dSArmin Le Grand 
468ddde725dSArmin Le Grand             if(mpXLink)
469ddde725dSArmin Le Grand             {
470ddde725dSArmin Le Grand                 return mpXLink->getFy();
471ddde725dSArmin Le Grand             }
472ddde725dSArmin Le Grand 
473ddde725dSArmin Le Grand             return 0;
474ddde725dSArmin Le Grand         }
475ddde725dSArmin Le Grand 
476ddde725dSArmin Le Grand         const basegfx::B2DHomMatrix* SvgGradientNode::getGradientTransform() const
477ddde725dSArmin Le Grand         {
478ddde725dSArmin Le Grand             if(mpaGradientTransform)
479ddde725dSArmin Le Grand             {
480ddde725dSArmin Le Grand                 return mpaGradientTransform;
481ddde725dSArmin Le Grand             }
482ddde725dSArmin Le Grand 
483ddde725dSArmin Le Grand             const_cast< SvgGradientNode* >(this)->tryToFindLink();
484ddde725dSArmin Le Grand 
485ddde725dSArmin Le Grand             if(mpXLink)
486ddde725dSArmin Le Grand             {
487ddde725dSArmin Le Grand                 return mpXLink->getGradientTransform();
488ddde725dSArmin Le Grand             }
489ddde725dSArmin Le Grand 
490ddde725dSArmin Le Grand             return 0;
491ddde725dSArmin Le Grand         }
492ddde725dSArmin Le Grand 
493ddde725dSArmin Le Grand         void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix* pMatrix)
494ddde725dSArmin Le Grand         {
495ddde725dSArmin Le Grand             if(mpaGradientTransform)
496ddde725dSArmin Le Grand             {
497ddde725dSArmin Le Grand                 delete mpaGradientTransform;
498ddde725dSArmin Le Grand                 mpaGradientTransform = 0;
499ddde725dSArmin Le Grand             }
500ddde725dSArmin Le Grand 
501ddde725dSArmin Le Grand             if(pMatrix)
502ddde725dSArmin Le Grand             {
503ddde725dSArmin Le Grand                 mpaGradientTransform = new basegfx::B2DHomMatrix(*pMatrix);
504ddde725dSArmin Le Grand             }
505ddde725dSArmin Le Grand         }
506ddde725dSArmin Le Grand 
507ddde725dSArmin Le Grand     } // end of namespace svgreader
508ddde725dSArmin Le Grand } // end of namespace svgio
509ddde725dSArmin Le Grand 
510ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
511ddde725dSArmin Le Grand // eof
512