1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
28 void SvgGradientNode::tryToFindLink()
30 if(!mpXLink
&& !maXLink
.isEmpty())
32 mpXLink
= dynamic_cast< const SvgGradientNode
* >(getDocument().findSvgNodeById(maXLink
));
36 SvgGradientNode::SvgGradientNode(
38 SvgDocument
& rDocument
,
40 : SvgNode(aType
, rDocument
, pParent
),
41 maSvgStyleAttributes(*this),
51 maGradientUnits(objectBoundingBox
),
52 maSpreadMethod(drawinglayer::primitive2d::Spread_pad
),
53 mpaGradientTransform(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
)
79 SvgNode::parseAttribute(rTokenName
, aSVGToken
, aContent
);
81 // read style attributes
82 maSvgStyleAttributes
.parseStyleAttribute(rTokenName
, aSVGToken
, aContent
, false);
89 readLocalCssStyle(aContent
);
96 if(readSingleNumber(aContent
, aNum
))
106 if(readSingleNumber(aContent
, aNum
))
116 if(readSingleNumber(aContent
, aNum
))
126 if(readSingleNumber(aContent
, aNum
))
136 if(readSingleNumber(aContent
, aNum
))
146 if(readSingleNumber(aContent
, aNum
))
156 if(readSingleNumber(aContent
, aNum
))
166 if(readSingleNumber(aContent
, aNum
))
176 if(readSingleNumber(aContent
, aNum
))
178 if(aNum
.isPositive())
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
);
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
);
219 case SVGTokenGradientTransform
:
221 const basegfx::B2DHomMatrix
aMatrix(readTransform(aContent
, *this));
223 if(!aMatrix
.isIdentity())
225 setGradientTransform(&aMatrix
);
229 case SVGTokenXlinkHref
:
231 const sal_Int32
nLen(aContent
.getLength());
233 if(nLen
&& '#' == aContent
[0])
235 maXLink
= aContent
.copy(1);
247 void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector
& aVector
) const
249 if(getChildren().empty())
251 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
255 mpXLink
->collectGradientEntries(aVector
);
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
]);
268 const SvgStyleAttributes
* pStyle
= pCandidate
->getSvgStyleAttributes();
272 const SvgNumber
aOffset(pCandidate
->getOffset());
275 if(Unit_percent
== aOffset
.getUnit())
277 // percent is not relative to distances in ColorStop context, solve locally
278 fOffset
= aOffset
.getNumber() * 0.01;
282 fOffset
= aOffset
.solve(*this);
287 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
290 else if(fOffset
> 1.0)
292 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
297 drawinglayer::primitive2d::SvgGradientEntry(
299 pStyle
->getStopColor(),
300 pStyle
->getStopOpacity().solve(*this)));
304 OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
311 const SvgNumber
SvgGradientNode::getX1() const
318 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
322 return mpXLink
->getX1();
326 return SvgNumber(0.0, Unit_percent
);
329 const SvgNumber
SvgGradientNode::getY1() const
336 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
340 return mpXLink
->getY1();
344 return SvgNumber(0.0, Unit_percent
);
347 const SvgNumber
SvgGradientNode::getX2() const
354 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
358 return mpXLink
->getX2();
362 return SvgNumber(100.0, Unit_percent
);
365 const SvgNumber
SvgGradientNode::getY2() const
372 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
376 return mpXLink
->getY2();
380 return SvgNumber(0.0, Unit_percent
);
383 const SvgNumber
SvgGradientNode::getCx() const
390 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
394 return mpXLink
->getCx();
398 return SvgNumber(50.0, Unit_percent
);
401 const SvgNumber
SvgGradientNode::getCy() const
408 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
412 return mpXLink
->getCy();
416 return SvgNumber(50.0, Unit_percent
);
419 const SvgNumber
SvgGradientNode::getR() const
426 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
430 return mpXLink
->getR();
434 return SvgNumber(50.0, Unit_percent
);
437 const SvgNumber
* SvgGradientNode::getFx() const
444 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
448 return mpXLink
->getFx();
454 const SvgNumber
* SvgGradientNode::getFy() const
461 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
465 return mpXLink
->getFy();
471 const basegfx::B2DHomMatrix
* SvgGradientNode::getGradientTransform() const
473 if(mpaGradientTransform
)
475 return mpaGradientTransform
;
478 const_cast< SvgGradientNode
* >(this)->tryToFindLink();
482 return mpXLink
->getGradientTransform();
488 void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix
* pMatrix
)
490 if(mpaGradientTransform
)
492 delete mpaGradientTransform
;
493 mpaGradientTransform
= 0;
498 mpaGradientTransform
= new basegfx::B2DHomMatrix(*pMatrix
);
502 } // end of namespace svgreader
503 } // end of namespace svgio
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */