Updated core
[LibreOffice.git] / svgio / source / svgreader / svggradientnode.cxx
blob3bc72e5ef92a9f89bd2d2aa401a1a841b8b1c761
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 namespace svgio
26 namespace svgreader
28 void SvgGradientNode::tryToFindLink()
30 if(!mpXLink && !maXLink.isEmpty())
32 mpXLink = dynamic_cast< const SvgGradientNode* >(getDocument().findSvgNodeById(maXLink));
36 SvgGradientNode::SvgGradientNode(
37 SVGToken aType,
38 SvgDocument& rDocument,
39 SvgNode* pParent)
40 : SvgNode(aType, rDocument, pParent),
41 maSvgStyleAttributes(*this),
42 maX1(),
43 maY1(),
44 maX2(),
45 maY2(),
46 maCx(),
47 maCy(),
48 maR(),
49 maFx(),
50 maFy(),
51 maGradientUnits(objectBoundingBox),
52 maSpreadMethod(drawinglayer::primitive2d::Spread_pad),
53 mpaGradientTransform(0),
54 maXLink(),
55 mpXLink(0)
57 OSL_ENSURE(aType == SVGTokenLinearGradient || aType == SVGTokenRadialGradient, "SvgGradientNode should ony be used for Linear and Radial gradient (!)");
60 SvgGradientNode::~SvgGradientNode()
62 if(mpaGradientTransform) delete mpaGradientTransform;
63 // do NOT delete mpXLink, it's only referenced, not owned
66 const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
68 OUString aClassStrA("linearGradient");
69 OUString aClassStrB("radialGradient");
71 return checkForCssStyle(
72 SVGTokenLinearGradient == getType() ? aClassStrA : aClassStrB,
73 maSvgStyleAttributes);
76 void SvgGradientNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent)
78 // call parent
79 SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
81 // read style attributes
82 maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent, false);
84 // parse own
85 switch(aSVGToken)
87 case SVGTokenStyle:
89 readLocalCssStyle(aContent);
90 break;
92 case SVGTokenX1:
94 SvgNumber aNum;
96 if(readSingleNumber(aContent, aNum))
98 setX1(aNum);
100 break;
102 case SVGTokenY1:
104 SvgNumber aNum;
106 if(readSingleNumber(aContent, aNum))
108 setY1(aNum);
110 break;
112 case SVGTokenX2:
114 SvgNumber aNum;
116 if(readSingleNumber(aContent, aNum))
118 setX2(aNum);
120 break;
122 case SVGTokenY2:
124 SvgNumber aNum;
126 if(readSingleNumber(aContent, aNum))
128 setY2(aNum);
130 break;
132 case SVGTokenCx:
134 SvgNumber aNum;
136 if(readSingleNumber(aContent, aNum))
138 setCx(aNum);
140 break;
142 case SVGTokenCy:
144 SvgNumber aNum;
146 if(readSingleNumber(aContent, aNum))
148 setCy(aNum);
150 break;
152 case SVGTokenFx:
154 SvgNumber aNum;
156 if(readSingleNumber(aContent, aNum))
158 setFx(aNum);
160 break;
162 case SVGTokenFy:
164 SvgNumber aNum;
166 if(readSingleNumber(aContent, aNum))
168 setFy(aNum);
170 break;
172 case SVGTokenR:
174 SvgNumber aNum;
176 if(readSingleNumber(aContent, aNum))
178 if(aNum.isPositive())
180 setR(aNum);
183 break;
185 case SVGTokenGradientUnits:
187 if(!aContent.isEmpty())
189 if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
191 setGradientUnits(userSpaceOnUse);
193 else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
195 setGradientUnits(objectBoundingBox);
198 break;
200 case SVGTokenSpreadMethod:
202 if(!aContent.isEmpty())
204 if(aContent.startsWith("pad"))
206 setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
208 else if(aContent.startsWith("reflect"))
210 setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
212 else if(aContent.startsWith("repeat"))
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 && '#' == 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 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */