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 return checkForCssStyle(aClassStr
, maSvgStyleAttributes
);
71 void SvgPatternNode::parseAttribute(const OUString
& rTokenName
, SVGToken aSVGToken
, const OUString
& aContent
)
74 SvgNode::parseAttribute(rTokenName
, aSVGToken
, aContent
);
76 // read style attributes
77 maSvgStyleAttributes
.parseStyleAttribute(rTokenName
, aSVGToken
, aContent
);
84 maSvgStyleAttributes
.readStyle(aContent
);
89 const basegfx::B2DRange
aRange(readViewBox(aContent
, *this));
97 case SVGTokenPreserveAspectRatio
:
99 setSvgAspectRatio(readSvgAspectRatio(aContent
));
106 if(readSingleNumber(aContent
, aNum
))
116 if(readSingleNumber(aContent
, aNum
))
126 if(readSingleNumber(aContent
, aNum
))
128 if(aNum
.isPositive())
139 if(readSingleNumber(aContent
, aNum
))
141 if(aNum
.isPositive())
148 case SVGTokenPatternUnits
:
150 if(aContent
.getLength())
152 if(aContent
.match(commonStrings::aStrUserSpaceOnUse
, 0))
154 setPatternUnits(userSpaceOnUse
);
156 else if(aContent
.match(commonStrings::aStrObjectBoundingBox
, 0))
158 setPatternUnits(objectBoundingBox
);
163 case SVGTokenPatternContentUnits
:
165 if(aContent
.getLength())
167 if(aContent
.match(commonStrings::aStrUserSpaceOnUse
, 0))
169 setPatternContentUnits(userSpaceOnUse
);
171 else if(aContent
.match(commonStrings::aStrObjectBoundingBox
, 0))
173 setPatternContentUnits(objectBoundingBox
);
178 case SVGTokenPatternTransform
:
180 const basegfx::B2DHomMatrix
aMatrix(readTransform(aContent
, *this));
182 if(!aMatrix
.isIdentity())
184 setPatternTransform(&aMatrix
);
188 case SVGTokenXlinkHref
:
190 const sal_Int32
nLen(aContent
.getLength());
192 if(nLen
&& sal_Unicode('#') == aContent
[0])
194 maXLink
= aContent
.copy(1);
206 void SvgPatternNode::getValuesRelative(double& rfX
, double& rfY
, double& rfW
, double& rfH
, const basegfx::B2DRange
& rGeoRange
, SvgNode
& rUser
) const
208 double fTargetWidth(rGeoRange
.getWidth());
209 double fTargetHeight(rGeoRange
.getHeight());
211 if(fTargetWidth
> 0.0 && fTargetHeight
> 0.0)
213 const SvgUnits
aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox
);
215 if(objectBoundingBox
== aPatternUnits
)
217 rfW
= (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
218 rfH
= (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
220 if(Unit_percent
== getWidth().getUnit())
225 if(Unit_percent
== getHeight().getUnit())
232 rfW
= (getWidth().isSet()) ? getWidth().solve(rUser
, xcoordinate
) : 0.0;
233 rfH
= (getHeight().isSet()) ? getHeight().solve(rUser
, ycoordinate
) : 0.0;
235 // make relative to rGeoRange
237 rfH
/= fTargetHeight
;
240 if(rfW
> 0.0 && rfH
> 0.0)
242 if(objectBoundingBox
== aPatternUnits
)
244 rfX
= (getX().isSet()) ? getX().getNumber() : 0.0;
245 rfY
= (getY().isSet()) ? getY().getNumber() : 0.0;
247 if(Unit_percent
== getX().getUnit())
252 if(Unit_percent
== getY().getUnit())
259 rfX
= (getX().isSet()) ? getX().solve(rUser
, xcoordinate
) : 0.0;
260 rfY
= (getY().isSet()) ? getY().solve(rUser
, ycoordinate
) : 0.0;
262 // make relative to rGeoRange
263 rfX
= (rfX
- rGeoRange
.getMinX()) / fTargetWidth
;
264 rfY
= (rfY
- rGeoRange
.getMinY()) / fTargetHeight
;
270 const drawinglayer::primitive2d::Primitive2DSequence
& SvgPatternNode::getPatternPrimitives() const
272 if(!aPrimitives
.hasElements())
274 decomposeSvgNode(const_cast< SvgPatternNode
* >(this)->aPrimitives
, true);
277 if(!aPrimitives
.hasElements() && maXLink
.getLength())
279 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
283 return mpXLink
->getPatternPrimitives();
290 const basegfx::B2DRange
* SvgPatternNode::getCurrentViewPort() const
298 return SvgNode::getCurrentViewPort();
302 const basegfx::B2DRange
* SvgPatternNode::getViewBox() const
309 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
313 return mpXLink
->getViewBox();
319 const SvgAspectRatio
& SvgPatternNode::getSvgAspectRatio() const
321 if(maSvgAspectRatio
.isSet())
323 return maSvgAspectRatio
;
326 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
330 return mpXLink
->getSvgAspectRatio();
333 return maSvgAspectRatio
;
336 const SvgNumber
& SvgPatternNode::getX() const
343 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
347 return mpXLink
->getX();
353 const SvgNumber
& SvgPatternNode::getY() const
360 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
364 return mpXLink
->getY();
370 const SvgNumber
& SvgPatternNode::getWidth() const
377 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
381 return mpXLink
->getWidth();
387 const SvgNumber
& SvgPatternNode::getHeight() const
394 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
398 return mpXLink
->getHeight();
404 const SvgUnits
* SvgPatternNode::getPatternUnits() const
408 return mpPatternUnits
;
411 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
415 return mpXLink
->getPatternUnits();
421 const SvgUnits
* SvgPatternNode::getPatternContentUnits() const
423 if(mpPatternContentUnits
)
425 return mpPatternContentUnits
;
428 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
432 return mpXLink
->getPatternContentUnits();
438 const basegfx::B2DHomMatrix
* SvgPatternNode::getPatternTransform() const
440 if(mpaPatternTransform
)
442 return mpaPatternTransform
;
445 const_cast< SvgPatternNode
* >(this)->tryToFindLink();
449 return mpXLink
->getPatternTransform();
455 } // end of namespace svgreader
456 } // end of namespace svgio
458 //////////////////////////////////////////////////////////////////////////////
461 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */