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/svgpatternnode.hxx>
21 #include <svgio/svgreader/svgdocument.hxx>
23 //////////////////////////////////////////////////////////////////////////////
29 void SvgPatternNode::tryToFindLink()
31 if(!mpXLink
&& maXLink
.getLength())
33 mpXLink
= dynamic_cast< const SvgPatternNode
* >(getDocument().findSvgNodeById(maXLink
));
37 SvgPatternNode::SvgPatternNode(
38 SvgDocument
& rDocument
,
40 : SvgNode(SVGTokenPattern
, rDocument
, pParent
),
42 maSvgStyleAttributes(*this),
50 mpPatternContentUnits(0),
51 mpaPatternTransform(0),
57 SvgPatternNode::~SvgPatternNode()
59 if(mpViewBox
) delete mpViewBox
;
60 if(mpaPatternTransform
) delete mpaPatternTransform
;
61 if(mpPatternUnits
) delete mpPatternUnits
;
62 if(mpPatternContentUnits
) delete mpPatternContentUnits
;
65 const SvgStyleAttributes
* SvgPatternNode::getSvgStyleAttributes() const
67 static rtl::OUString
aClassStr(rtl::OUString::createFromAscii("pattern"));
68 maSvgStyleAttributes
.checkForCssStyle(aClassStr
);
70 return &maSvgStyleAttributes
;
73 void SvgPatternNode::parseAttribute(const rtl::OUString
& rTokenName
, SVGToken aSVGToken
, const rtl::OUString
& aContent
)
76 SvgNode::parseAttribute(rTokenName
, aSVGToken
, aContent
);
78 // read style attributes
79 maSvgStyleAttributes
.parseStyleAttribute(rTokenName
, aSVGToken
, aContent
);
86 maSvgStyleAttributes
.readStyle(aContent
);
91 const basegfx::B2DRange
aRange(readViewBox(aContent
, *this));
99 case SVGTokenPreserveAspectRatio
:
101 setSvgAspectRatio(readSvgAspectRatio(aContent
));
108 if(readSingleNumber(aContent
, aNum
))
118 if(readSingleNumber(aContent
, aNum
))
128 if(readSingleNumber(aContent
, aNum
))
130 if(aNum
.isPositive())
141 if(readSingleNumber(aContent
, aNum
))
143 if(aNum
.isPositive())
150 case SVGTokenPatternUnits
:
152 if(aContent
.getLength())
154 if(aContent
.match(commonStrings::aStrUserSpaceOnUse
, 0))
156 setPatternUnits(userSpaceOnUse
);
158 else if(aContent
.match(commonStrings::aStrObjectBoundingBox
, 0))
160 setPatternUnits(objectBoundingBox
);
165 case SVGTokenPatternContentUnits
:
167 if(aContent
.getLength())
169 if(aContent
.match(commonStrings::aStrUserSpaceOnUse
, 0))
171 setPatternContentUnits(userSpaceOnUse
);
173 else if(aContent
.match(commonStrings::aStrObjectBoundingBox
, 0))
175 setPatternContentUnits(objectBoundingBox
);
180 case SVGTokenPatternTransform
:
182 const basegfx::B2DHomMatrix
aMatrix(readTransform(aContent
, *this));
184 if(!aMatrix
.isIdentity())
186 setPatternTransform(&aMatrix
);
190 case SVGTokenXlinkHref
:
192 const sal_Int32
nLen(aContent
.getLength());
194 if(nLen
&& sal_Unicode('#') == aContent
[0])
196 maXLink
= aContent
.copy(1);
208 void SvgPatternNode::getValuesRelative(double& rfX
, double& rfY
, double& rfW
, double& rfH
, const basegfx::B2DRange
& rGeoRange
, SvgNode
& rUser
) const
210 double fTargetWidth(rGeoRange
.getWidth());
211 double fTargetHeight(rGeoRange
.getHeight());
213 if(fTargetWidth
> 0.0 && fTargetHeight
> 0.0)
215 const SvgUnits
aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox
);
217 if(objectBoundingBox
== aPatternUnits
)
219 rfW
= (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
220 rfH
= (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
222 if(Unit_percent
== getWidth().getUnit())
227 if(Unit_percent
== getHeight().getUnit())
234 rfW
= (getWidth().isSet()) ? getWidth().solve(rUser
, xcoordinate
) : 0.0;
235 rfH
= (getHeight().isSet()) ? getHeight().solve(rUser
, ycoordinate
) : 0.0;
237 // make relative to rGeoRange
239 rfH
/= fTargetHeight
;
242 if(rfW
> 0.0 && rfH
> 0.0)
244 if(objectBoundingBox
== aPatternUnits
)
246 rfX
= (getX().isSet()) ? getX().getNumber() : 0.0;
247 rfY
= (getY().isSet()) ? getY().getNumber() : 0.0;
249 if(Unit_percent
== getX().getUnit())
254 if(Unit_percent
== getY().getUnit())
261 rfX
= (getX().isSet()) ? getX().solve(rUser
, xcoordinate
) : 0.0;
262 rfY
= (getY().isSet()) ? getY().solve(rUser
, ycoordinate
) : 0.0;
264 // make relative to rGeoRange
265 rfX
= (rfX
- rGeoRange
.getMinX()) / fTargetWidth
;
266 rfY
= (rfY
- rGeoRange
.getMinY()) / fTargetHeight
;
272 const drawinglayer::primitive2d::Primitive2DSequence
& SvgPatternNode::getPatternPrimitives() const
274 if(!aPrimitives
.hasElements())
276 decomposeSvgNode(const_cast< SvgPatternNode
* >(this)->aPrimitives
, true);
279 if(!aPrimitives
.hasElements() && maXLink
.getLength())
281 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
285 return mpXLink
->getPatternPrimitives();
292 const basegfx::B2DRange
* SvgPatternNode::getCurrentViewPort() const
300 return SvgNode::getCurrentViewPort();
304 const basegfx::B2DRange
* SvgPatternNode::getViewBox() const
311 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
315 return mpXLink
->getViewBox();
321 const SvgAspectRatio
& SvgPatternNode::getSvgAspectRatio() const
323 if(maSvgAspectRatio
.isSet())
325 return maSvgAspectRatio
;
328 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
332 return mpXLink
->getSvgAspectRatio();
335 return maSvgAspectRatio
;
338 const SvgNumber
& SvgPatternNode::getX() const
345 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
349 return mpXLink
->getX();
355 const SvgNumber
& SvgPatternNode::getY() const
362 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
366 return mpXLink
->getY();
372 const SvgNumber
& SvgPatternNode::getWidth() const
379 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
383 return mpXLink
->getWidth();
389 const SvgNumber
& SvgPatternNode::getHeight() const
396 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
400 return mpXLink
->getHeight();
406 const SvgUnits
* SvgPatternNode::getPatternUnits() const
410 return mpPatternUnits
;
413 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
417 return mpXLink
->getPatternUnits();
423 const SvgUnits
* SvgPatternNode::getPatternContentUnits() const
425 if(mpPatternContentUnits
)
427 return mpPatternContentUnits
;
430 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
434 return mpXLink
->getPatternContentUnits();
440 const basegfx::B2DHomMatrix
* SvgPatternNode::getPatternTransform() const
442 if(mpaPatternTransform
)
444 return mpaPatternTransform
;
447 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
451 return mpXLink
->getPatternTransform();
457 } // end of namespace svgreader
458 } // end of namespace svgio
460 //////////////////////////////////////////////////////////////////////////////
463 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */