bump product version to 7.2.5.1
[LibreOffice.git] / svgio / source / svgreader / svgpatternnode.cxx
blob8d8721a5ee27cee03dacfc09585899df92295cc1
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 <svgpatternnode.hxx>
21 #include <svgdocument.hxx>
23 namespace svgio::svgreader
25 void SvgPatternNode::tryToFindLink()
27 if(!mpXLink && !maXLink.isEmpty())
29 mpXLink = dynamic_cast< const SvgPatternNode* >(getDocument().findSvgNodeById(maXLink));
33 SvgPatternNode::SvgPatternNode(
34 SvgDocument& rDocument,
35 SvgNode* pParent)
36 : SvgNode(SVGToken::Pattern, rDocument, pParent),
37 aPrimitives(),
38 maSvgStyleAttributes(*this),
39 maSvgAspectRatio(),
40 maX(),
41 maY(),
42 maWidth(),
43 maHeight(),
44 mbResolvingLink(false),
45 maXLink(),
46 mpXLink(nullptr)
50 SvgPatternNode::~SvgPatternNode()
54 const SvgStyleAttributes* SvgPatternNode::getSvgStyleAttributes() const
56 return checkForCssStyle("pattern", maSvgStyleAttributes);
59 void SvgPatternNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent)
61 // call parent
62 SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
64 // read style attributes
65 maSvgStyleAttributes.parseStyleAttribute(aSVGToken, aContent, false);
67 // parse own
68 switch(aSVGToken)
70 case SVGToken::Style:
72 readLocalCssStyle(aContent);
73 break;
75 case SVGToken::ViewBox:
77 const basegfx::B2DRange aRange(readViewBox(aContent, *this));
79 if(!aRange.isEmpty())
81 setViewBox(&aRange);
83 break;
85 case SVGToken::PreserveAspectRatio:
87 maSvgAspectRatio = readSvgAspectRatio(aContent);
88 break;
90 case SVGToken::X:
92 SvgNumber aNum;
94 if(readSingleNumber(aContent, aNum))
96 maX = aNum;
98 break;
100 case SVGToken::Y:
102 SvgNumber aNum;
104 if(readSingleNumber(aContent, aNum))
106 maY = aNum;
108 break;
110 case SVGToken::Width:
112 SvgNumber aNum;
114 if(readSingleNumber(aContent, aNum))
116 if(aNum.isPositive())
118 maWidth = aNum;
121 break;
123 case SVGToken::Height:
125 SvgNumber aNum;
127 if(readSingleNumber(aContent, aNum))
129 if(aNum.isPositive())
131 maHeight = aNum;
134 break;
136 case SVGToken::PatternUnits:
138 if(!aContent.isEmpty())
140 if(aContent.match(commonStrings::aStrUserSpaceOnUse))
142 setPatternUnits(SvgUnits::userSpaceOnUse);
144 else if(aContent.match(commonStrings::aStrObjectBoundingBox))
146 setPatternUnits(SvgUnits::objectBoundingBox);
149 break;
151 case SVGToken::PatternContentUnits:
153 if(!aContent.isEmpty())
155 if(aContent.match(commonStrings::aStrUserSpaceOnUse))
157 setPatternContentUnits(SvgUnits::userSpaceOnUse);
159 else if(aContent.match(commonStrings::aStrObjectBoundingBox))
161 setPatternContentUnits(SvgUnits::objectBoundingBox);
164 break;
166 case SVGToken::PatternTransform:
168 const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
170 if(!aMatrix.isIdentity())
172 setPatternTransform(&aMatrix);
174 break;
176 case SVGToken::XlinkHref:
178 const sal_Int32 nLen(aContent.getLength());
180 if(nLen && '#' == aContent[0])
182 maXLink = aContent.copy(1);
183 tryToFindLink();
185 break;
187 default:
189 break;
194 void SvgPatternNode::getValuesRelative(double& rfX, double& rfY, double& rfW, double& rfH, const basegfx::B2DRange& rGeoRange, SvgNode const & rUser) const
196 double fTargetWidth(rGeoRange.getWidth());
197 double fTargetHeight(rGeoRange.getHeight());
199 if(fTargetWidth <= 0.0 || fTargetHeight <= 0.0)
200 return;
202 const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : SvgUnits::objectBoundingBox);
204 if (SvgUnits::objectBoundingBox == aPatternUnits)
206 rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
207 rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
209 if(SvgUnit::percent == getWidth().getUnit())
211 rfW *= 0.01;
214 if(SvgUnit::percent == getHeight().getUnit())
216 rfH *= 0.01;
219 else
221 rfW = (getWidth().isSet()) ? getWidth().solve(rUser, NumberType::xcoordinate) : 0.0;
222 rfH = (getHeight().isSet()) ? getHeight().solve(rUser, NumberType::ycoordinate) : 0.0;
224 // make relative to rGeoRange
225 rfW /= fTargetWidth;
226 rfH /= fTargetHeight;
229 if(rfW <= 0.0 || rfH <= 0.0)
230 return;
232 if (SvgUnits::objectBoundingBox == aPatternUnits)
234 rfX = (getX().isSet()) ? getX().getNumber() : 0.0;
235 rfY = (getY().isSet()) ? getY().getNumber() : 0.0;
237 if(SvgUnit::percent == getX().getUnit())
239 rfX *= 0.01;
242 if(SvgUnit::percent == getY().getUnit())
244 rfY *= 0.01;
247 else
249 rfX = (getX().isSet()) ? getX().solve(rUser, NumberType::xcoordinate) : 0.0;
250 rfY = (getY().isSet()) ? getY().solve(rUser, NumberType::ycoordinate) : 0.0;
252 // make relative to rGeoRange
253 rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth;
254 rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight;
258 const drawinglayer::primitive2d::Primitive2DContainer& SvgPatternNode::getPatternPrimitives() const
260 if(aPrimitives.empty() && Display::None != getDisplay())
262 decomposeSvgNode(const_cast< SvgPatternNode* >(this)->aPrimitives, true);
265 if(aPrimitives.empty() && !maXLink.isEmpty())
267 const_cast< SvgPatternNode* >(this)->tryToFindLink();
269 if (mpXLink && !mbResolvingLink)
271 mbResolvingLink = true;
272 const drawinglayer::primitive2d::Primitive2DContainer& ret = mpXLink->getPatternPrimitives();
273 mbResolvingLink = false;
274 return ret;
278 return aPrimitives;
281 basegfx::B2DRange SvgPatternNode::getCurrentViewPort() const
283 if(getViewBox())
285 return *(getViewBox());
287 else
289 return SvgNode::getCurrentViewPort();
293 const basegfx::B2DRange* SvgPatternNode::getViewBox() const
295 if(mpViewBox)
297 return mpViewBox.get();
300 const_cast< SvgPatternNode* >(this)->tryToFindLink();
302 if (mpXLink && !mbResolvingLink)
304 mbResolvingLink = true;
305 auto ret = mpXLink->getViewBox();
306 mbResolvingLink = false;
307 return ret;
310 return nullptr;
313 const SvgAspectRatio& SvgPatternNode::getSvgAspectRatio() const
315 if(maSvgAspectRatio.isSet())
317 return maSvgAspectRatio;
320 const_cast< SvgPatternNode* >(this)->tryToFindLink();
322 if (mpXLink && !mbResolvingLink)
324 mbResolvingLink = true;
325 const SvgAspectRatio& ret = mpXLink->getSvgAspectRatio();
326 mbResolvingLink = false;
327 return ret;
330 return maSvgAspectRatio;
333 const SvgNumber& SvgPatternNode::getX() const
335 if(maX.isSet())
337 return maX;
340 const_cast< SvgPatternNode* >(this)->tryToFindLink();
342 if (mpXLink && !mbResolvingLink)
344 mbResolvingLink = true;
345 const SvgNumber& ret = mpXLink->getX();
346 mbResolvingLink = false;
347 return ret;
350 return maX;
353 const SvgNumber& SvgPatternNode::getY() const
355 if(maY.isSet())
357 return maY;
360 const_cast< SvgPatternNode* >(this)->tryToFindLink();
362 if (mpXLink && !mbResolvingLink)
364 mbResolvingLink = true;
365 const SvgNumber& ret = mpXLink->getY();
366 mbResolvingLink = false;
367 return ret;
370 return maY;
373 const SvgNumber& SvgPatternNode::getWidth() const
375 if(maWidth.isSet())
377 return maWidth;
380 const_cast< SvgPatternNode* >(this)->tryToFindLink();
382 if (mpXLink && !mbResolvingLink)
384 mbResolvingLink = true;
385 const SvgNumber& ret = mpXLink->getWidth();
386 mbResolvingLink = false;
387 return ret;
390 return maWidth;
393 const SvgNumber& SvgPatternNode::getHeight() const
395 if(maHeight.isSet())
397 return maHeight;
400 const_cast< SvgPatternNode* >(this)->tryToFindLink();
402 if (mpXLink && !mbResolvingLink)
404 mbResolvingLink = true;
405 const SvgNumber& ret = mpXLink->getHeight();
406 mbResolvingLink = false;
407 return ret;
410 return maHeight;
413 const SvgUnits* SvgPatternNode::getPatternUnits() const
415 if(mpPatternUnits)
417 return mpPatternUnits.get();
420 const_cast< SvgPatternNode* >(this)->tryToFindLink();
422 if (mpXLink && !mbResolvingLink)
424 mbResolvingLink = true;
425 auto ret = mpXLink->getPatternUnits();
426 mbResolvingLink = false;
427 return ret;
430 return nullptr;
433 const SvgUnits* SvgPatternNode::getPatternContentUnits() const
435 if(mpPatternContentUnits)
437 return mpPatternContentUnits.get();
440 const_cast< SvgPatternNode* >(this)->tryToFindLink();
442 if (mpXLink && !mbResolvingLink)
444 mbResolvingLink = true;
445 auto ret = mpXLink->getPatternContentUnits();
446 mbResolvingLink = false;
447 return ret;
450 return nullptr;
453 const basegfx::B2DHomMatrix* SvgPatternNode::getPatternTransform() const
455 if(mpaPatternTransform)
457 return mpaPatternTransform.get();
460 const_cast< SvgPatternNode* >(this)->tryToFindLink();
462 if (mpXLink && !mbResolvingLink)
464 mbResolvingLink = true;
465 auto ret = mpXLink->getPatternTransform();
466 mbResolvingLink = false;
467 return ret;
470 return nullptr;
473 } // end of namespace svgio::svgreader
475 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */