update credits
[LibreOffice.git] / svgio / source / svgreader / svggradientnode.cxx
blob215ce391b460203443329bc83796c2051ae23ef0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svgio/svgreader/svggradientnode.hxx>
21 #include <svgio/svgreader/svgdocument.hxx>
22 #include <svgio/svgreader/svggradientstopnode.hxx>
24 //////////////////////////////////////////////////////////////////////////////
26 namespace svgio
28 namespace svgreader
30 void SvgGradientNode::tryToFindLink()
32 if(!mpXLink && maXLink.getLength())
34 mpXLink = dynamic_cast< const SvgGradientNode* >(getDocument().findSvgNodeById(maXLink));
38 SvgGradientNode::SvgGradientNode(
39 SVGToken aType,
40 SvgDocument& rDocument,
41 SvgNode* pParent)
42 : SvgNode(aType, rDocument, pParent),
43 maSvgStyleAttributes(*this),
44 maX1(),
45 maY1(),
46 maX2(),
47 maY2(),
48 maCx(),
49 maCy(),
50 maR(),
51 maFx(),
52 maFy(),
53 maGradientUnits(objectBoundingBox),
54 maSpreadMethod(drawinglayer::primitive2d::Spread_pad),
55 mpaGradientTransform(0),
56 maXLink(),
57 mpXLink(0)
61 SvgGradientNode::~SvgGradientNode()
63 if(mpaGradientTransform) delete mpaGradientTransform;
64 // do NOT delete mpXLink, it's only referenced, not owned
67 const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
69 return &maSvgStyleAttributes;
72 void SvgGradientNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent)
74 // call parent
75 SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
77 // read style attributes
78 maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
80 // parse own
81 switch(aSVGToken)
83 case SVGTokenStyle:
85 maSvgStyleAttributes.readStyle(aContent);
86 break;
88 case SVGTokenX1:
90 SvgNumber aNum;
92 if(readSingleNumber(aContent, aNum))
94 setX1(aNum);
96 break;
98 case SVGTokenY1:
100 SvgNumber aNum;
102 if(readSingleNumber(aContent, aNum))
104 setY1(aNum);
106 break;
108 case SVGTokenX2:
110 SvgNumber aNum;
112 if(readSingleNumber(aContent, aNum))
114 setX2(aNum);
116 break;
118 case SVGTokenY2:
120 SvgNumber aNum;
122 if(readSingleNumber(aContent, aNum))
124 setY2(aNum);
126 break;
128 case SVGTokenCx:
130 SvgNumber aNum;
132 if(readSingleNumber(aContent, aNum))
134 setCx(aNum);
136 break;
138 case SVGTokenCy:
140 SvgNumber aNum;
142 if(readSingleNumber(aContent, aNum))
144 setCy(aNum);
146 break;
148 case SVGTokenFx:
150 SvgNumber aNum;
152 if(readSingleNumber(aContent, aNum))
154 setFx(aNum);
156 break;
158 case SVGTokenFy:
160 SvgNumber aNum;
162 if(readSingleNumber(aContent, aNum))
164 setFy(aNum);
166 break;
168 case SVGTokenR:
170 SvgNumber aNum;
172 if(readSingleNumber(aContent, aNum))
174 if(aNum.isPositive())
176 setR(aNum);
179 break;
181 case SVGTokenGradientUnits:
183 if(aContent.getLength())
185 if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
187 setGradientUnits(userSpaceOnUse);
189 else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
191 setGradientUnits(objectBoundingBox);
194 break;
196 case SVGTokenSpreadMethod:
198 if(aContent.getLength())
200 static OUString aStrPad(OUString::createFromAscii("pad"));
201 static OUString aStrReflect(OUString::createFromAscii("reflect"));
202 static OUString aStrRepeat(OUString::createFromAscii("repeat"));
204 if(aContent.match(aStrPad, 0))
206 setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
208 else if(aContent.match(aStrReflect, 0))
210 setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
212 else if(aContent.match(aStrRepeat, 0))
214 setSpreadMethod(drawinglayer::primitive2d::Spread_repeat);
217 break;
219 case SVGTokenGradientTransform:
221 const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
223 if(!aMatrix.isIdentity())
225 setGradientTransform(&aMatrix);
227 break;
229 case SVGTokenXlinkHref:
231 const sal_Int32 nLen(aContent.getLength());
233 if(nLen && sal_Unicode('#') == aContent[0])
235 maXLink = aContent.copy(1);
236 tryToFindLink();
238 break;
240 default:
242 break;
247 void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const
249 if(getChildren().empty())
251 const_cast< SvgGradientNode* >(this)->tryToFindLink();
253 if(mpXLink)
255 mpXLink->collectGradientEntries(aVector);
258 else
260 const sal_uInt32 nCount(getChildren().size());
262 for(sal_uInt32 a(0); a < nCount; a++)
264 const SvgGradientStopNode* pCandidate = dynamic_cast< const SvgGradientStopNode* >(getChildren()[a]);
266 if(pCandidate)
268 const SvgStyleAttributes* pStyle = pCandidate->getSvgStyleAttributes();
270 if(pStyle)
272 const SvgNumber aOffset(pCandidate->getOffset());
273 double fOffset(0.0);
275 if(Unit_percent == aOffset.getUnit())
277 // percent is not relative to distances in ColorStop context, solve locally
278 fOffset = aOffset.getNumber() * 0.01;
280 else
282 fOffset = aOffset.solve(*this);
285 if(fOffset < 0.0)
287 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
288 fOffset = 0.0;
290 else if(fOffset > 1.0)
292 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
293 fOffset = 1.0;
296 aVector.push_back(
297 drawinglayer::primitive2d::SvgGradientEntry(
298 fOffset,
299 pStyle->getStopColor(),
300 pStyle->getStopOpacity().solve(*this)));
302 else
304 OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
311 const SvgNumber SvgGradientNode::getX1() const
313 if(maX1.isSet())
315 return maX1;
318 const_cast< SvgGradientNode* >(this)->tryToFindLink();
320 if(mpXLink)
322 return mpXLink->getX1();
325 // default is 0%
326 return SvgNumber(0.0, Unit_percent);
329 const SvgNumber SvgGradientNode::getY1() const
331 if(maY1.isSet())
333 return maY1;
336 const_cast< SvgGradientNode* >(this)->tryToFindLink();
338 if(mpXLink)
340 return mpXLink->getY1();
343 // default is 0%
344 return SvgNumber(0.0, Unit_percent);
347 const SvgNumber SvgGradientNode::getX2() const
349 if(maX2.isSet())
351 return maX2;
354 const_cast< SvgGradientNode* >(this)->tryToFindLink();
356 if(mpXLink)
358 return mpXLink->getX2();
361 // default is 100%
362 return SvgNumber(100.0, Unit_percent);
365 const SvgNumber SvgGradientNode::getY2() const
367 if(maY2.isSet())
369 return maY2;
372 const_cast< SvgGradientNode* >(this)->tryToFindLink();
374 if(mpXLink)
376 return mpXLink->getY2();
379 // default is 0%
380 return SvgNumber(0.0, Unit_percent);
383 const SvgNumber SvgGradientNode::getCx() const
385 if(maCx.isSet())
387 return maCx;
390 const_cast< SvgGradientNode* >(this)->tryToFindLink();
392 if(mpXLink)
394 return mpXLink->getCx();
397 // default is 50%
398 return SvgNumber(50.0, Unit_percent);
401 const SvgNumber SvgGradientNode::getCy() const
403 if(maCy.isSet())
405 return maCy;
408 const_cast< SvgGradientNode* >(this)->tryToFindLink();
410 if(mpXLink)
412 return mpXLink->getCy();
415 // default is 50%
416 return SvgNumber(50.0, Unit_percent);
419 const SvgNumber SvgGradientNode::getR() const
421 if(maR.isSet())
423 return maR;
426 const_cast< SvgGradientNode* >(this)->tryToFindLink();
428 if(mpXLink)
430 return mpXLink->getR();
433 // default is 50%
434 return SvgNumber(50.0, Unit_percent);
437 const SvgNumber* SvgGradientNode::getFx() const
439 if(maFx.isSet())
441 return &maFx;
444 const_cast< SvgGradientNode* >(this)->tryToFindLink();
446 if(mpXLink)
448 return mpXLink->getFx();
451 return 0;
454 const SvgNumber* SvgGradientNode::getFy() const
456 if(maFy.isSet())
458 return &maFy;
461 const_cast< SvgGradientNode* >(this)->tryToFindLink();
463 if(mpXLink)
465 return mpXLink->getFy();
468 return 0;
471 const basegfx::B2DHomMatrix* SvgGradientNode::getGradientTransform() const
473 if(mpaGradientTransform)
475 return mpaGradientTransform;
478 const_cast< SvgGradientNode* >(this)->tryToFindLink();
480 if(mpXLink)
482 return mpXLink->getGradientTransform();
485 return 0;
488 void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix* pMatrix)
490 if(mpaGradientTransform)
492 delete mpaGradientTransform;
493 mpaGradientTransform = 0;
496 if(pMatrix)
498 mpaGradientTransform = new basegfx::B2DHomMatrix(*pMatrix);
502 } // end of namespace svgreader
503 } // end of namespace svgio
505 //////////////////////////////////////////////////////////////////////////////
506 // eof
508 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */