/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svgio.hxx" #include #include ////////////////////////////////////////////////////////////////////////////// namespace svgio { namespace svgreader { void SvgPatternNode::tryToFindLink() { if(!mpXLink && maXLink.getLength()) { mpXLink = dynamic_cast< const SvgPatternNode* >(getDocument().findSvgNodeById(maXLink)); } } SvgPatternNode::SvgPatternNode( SvgDocument& rDocument, SvgNode* pParent) : SvgNode(SVGTokenPattern, rDocument, pParent), aPrimitives(), maSvgStyleAttributes(*this), mpViewBox(0), maSvgAspectRatio(), maX(), maY(), maWidth(), maHeight(), mpPatternUnits(0), mpPatternContentUnits(0), mpaPatternTransform(0), maXLink(), mpXLink(0) { } SvgPatternNode::~SvgPatternNode() { if(mpViewBox) delete mpViewBox; if(mpaPatternTransform) delete mpaPatternTransform; if(mpPatternUnits) delete mpPatternUnits; if(mpPatternContentUnits) delete mpPatternContentUnits; } const SvgStyleAttributes* SvgPatternNode::getSvgStyleAttributes() const { static rtl::OUString aClassStr(rtl::OUString::createFromAscii("pattern")); return checkForCssStyle(aClassStr, maSvgStyleAttributes); } void SvgPatternNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent) { // call parent SvgNode::parseAttribute(rTokenName, aSVGToken, aContent); // read style attributes maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent, false); // parse own switch(aSVGToken) { case SVGTokenStyle: { readLocalCssStyle(aContent); break; } case SVGTokenViewBox: { const basegfx::B2DRange aRange(readViewBox(aContent, *this)); if(!aRange.isEmpty()) { setViewBox(&aRange); } break; } case SVGTokenPreserveAspectRatio: { setSvgAspectRatio(readSvgAspectRatio(aContent)); break; } case SVGTokenX: { SvgNumber aNum; if(readSingleNumber(aContent, aNum)) { setX(aNum); } break; } case SVGTokenY: { SvgNumber aNum; if(readSingleNumber(aContent, aNum)) { setY(aNum); } break; } case SVGTokenWidth: { SvgNumber aNum; if(readSingleNumber(aContent, aNum)) { if(aNum.isPositive()) { setWidth(aNum); } } break; } case SVGTokenHeight: { SvgNumber aNum; if(readSingleNumber(aContent, aNum)) { if(aNum.isPositive()) { setHeight(aNum); } } break; } case SVGTokenPatternUnits: { if(aContent.getLength()) { if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0)) { setPatternUnits(userSpaceOnUse); } else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0)) { setPatternUnits(objectBoundingBox); } } break; } case SVGTokenPatternContentUnits: { if(aContent.getLength()) { if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0)) { setPatternContentUnits(userSpaceOnUse); } else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0)) { setPatternContentUnits(objectBoundingBox); } } break; } case SVGTokenPatternTransform: { const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this)); if(!aMatrix.isIdentity()) { setPatternTransform(&aMatrix); } break; } case SVGTokenXlinkHref: { const sal_Int32 nLen(aContent.getLength()); if(nLen && sal_Unicode('#') == aContent[0]) { maXLink = aContent.copy(1); tryToFindLink(); } break; } default: { break; } } } void SvgPatternNode::getValuesRelative(double& rfX, double& rfY, double& rfW, double& rfH, const basegfx::B2DRange& rGeoRange, SvgNode& rUser) const { double fTargetWidth(rGeoRange.getWidth()); double fTargetHeight(rGeoRange.getHeight()); if(fTargetWidth > 0.0 && fTargetHeight > 0.0) { const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox); if(objectBoundingBox == aPatternUnits) { rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0; rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0; if(Unit_percent == getWidth().getUnit()) { rfW *= 0.01; } if(Unit_percent == getHeight().getUnit()) { rfH *= 0.01; } } else { rfW = (getWidth().isSet()) ? getWidth().solve(rUser, xcoordinate) : 0.0; rfH = (getHeight().isSet()) ? getHeight().solve(rUser, ycoordinate) : 0.0; // make relative to rGeoRange rfW /= fTargetWidth; rfH /= fTargetHeight; } if(rfW > 0.0 && rfH > 0.0) { if(objectBoundingBox == aPatternUnits) { rfX = (getX().isSet()) ? getX().getNumber() : 0.0; rfY = (getY().isSet()) ? getY().getNumber() : 0.0; if(Unit_percent == getX().getUnit()) { rfX *= 0.01; } if(Unit_percent == getY().getUnit()) { rfY *= 0.01; } } else { rfX = (getX().isSet()) ? getX().solve(rUser, xcoordinate) : 0.0; rfY = (getY().isSet()) ? getY().solve(rUser, ycoordinate) : 0.0; // make relative to rGeoRange rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth; rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight; } } } } const drawinglayer::primitive2d::Primitive2DSequence& SvgPatternNode::getPatternPrimitives() const { if(!aPrimitives.hasElements() && Display_none != getDisplay()) { decomposeSvgNode(const_cast< SvgPatternNode* >(this)->aPrimitives, true); } if(!aPrimitives.hasElements() && maXLink.getLength()) { const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getPatternPrimitives(); } } return aPrimitives; } const basegfx::B2DRange SvgPatternNode::getCurrentViewPort() const { if(getViewBox()) { return *(getViewBox()); } else { return SvgNode::getCurrentViewPort(); } } const basegfx::B2DRange* SvgPatternNode::getViewBox() const { if(mpViewBox) { return mpViewBox; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getViewBox(); } return 0; } const SvgAspectRatio& SvgPatternNode::getSvgAspectRatio() const { if(maSvgAspectRatio.isSet()) { return maSvgAspectRatio; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getSvgAspectRatio(); } return maSvgAspectRatio; } const SvgNumber& SvgPatternNode::getX() const { if(maX.isSet()) { return maX; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getX(); } return maX; } const SvgNumber& SvgPatternNode::getY() const { if(maY.isSet()) { return maY; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getY(); } return maY; } const SvgNumber& SvgPatternNode::getWidth() const { if(maWidth.isSet()) { return maWidth; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getWidth(); } return maWidth; } const SvgNumber& SvgPatternNode::getHeight() const { if(maHeight.isSet()) { return maHeight; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getHeight(); } return maHeight; } const SvgUnits* SvgPatternNode::getPatternUnits() const { if(mpPatternUnits) { return mpPatternUnits; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getPatternUnits(); } return 0; } const SvgUnits* SvgPatternNode::getPatternContentUnits() const { if(mpPatternContentUnits) { return mpPatternContentUnits; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getPatternContentUnits(); } return 0; } const basegfx::B2DHomMatrix* SvgPatternNode::getPatternTransform() const { if(mpaPatternTransform) { return mpaPatternTransform; } const_cast< SvgPatternNode* >(this)->tryToFindLink(); if(mpXLink) { return mpXLink->getPatternTransform(); } return 0; } } // end of namespace svgreader } // end of namespace svgio ////////////////////////////////////////////////////////////////////////////// // eof