1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_svgio.hxx" 24 25 #include <svgio/svgreader/svgusenode.hxx> 26 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 27 #include <svgio/svgreader/svgdocument.hxx> 28 29 ////////////////////////////////////////////////////////////////////////////// 30 31 namespace svgio 32 { 33 namespace svgreader 34 { 35 SvgUseNode::SvgUseNode( 36 SvgDocument& rDocument, 37 SvgNode* pParent) 38 : SvgNode(SVGTokenG, rDocument, pParent), 39 maSvgStyleAttributes(*this), 40 mpaTransform(0), 41 maX(), 42 maY(), 43 maWidth(), 44 maHeight(), 45 maXLink() 46 { 47 } 48 49 SvgUseNode::~SvgUseNode() 50 { 51 if(mpaTransform) delete mpaTransform; 52 } 53 54 const SvgStyleAttributes* SvgUseNode::getSvgStyleAttributes() const 55 { 56 static rtl::OUString aClassStr(rtl::OUString::createFromAscii("use")); 57 maSvgStyleAttributes.checkForCssStyle(aClassStr); 58 59 return &maSvgStyleAttributes; 60 } 61 62 void SvgUseNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent) 63 { 64 // call parent 65 SvgNode::parseAttribute(rTokenName, aSVGToken, aContent); 66 67 // read style attributes 68 maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent); 69 70 // parse own 71 switch(aSVGToken) 72 { 73 case SVGTokenStyle: 74 { 75 maSvgStyleAttributes.readStyle(aContent); 76 break; 77 } 78 case SVGTokenTransform: 79 { 80 const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this)); 81 82 if(!aMatrix.isIdentity()) 83 { 84 setTransform(&aMatrix); 85 } 86 break; 87 } 88 case SVGTokenX: 89 { 90 SvgNumber aNum; 91 92 if(readSingleNumber(aContent, aNum)) 93 { 94 setX(aNum); 95 } 96 break; 97 } 98 case SVGTokenY: 99 { 100 SvgNumber aNum; 101 102 if(readSingleNumber(aContent, aNum)) 103 { 104 setY(aNum); 105 } 106 break; 107 } 108 case SVGTokenWidth: 109 { 110 SvgNumber aNum; 111 112 if(readSingleNumber(aContent, aNum)) 113 { 114 if(aNum.isPositive()) 115 { 116 setWidth(aNum); 117 } 118 } 119 break; 120 } 121 case SVGTokenHeight: 122 { 123 SvgNumber aNum; 124 125 if(readSingleNumber(aContent, aNum)) 126 { 127 if(aNum.isPositive()) 128 { 129 setHeight(aNum); 130 } 131 } 132 } 133 case SVGTokenXlinkHref: 134 { 135 const sal_Int32 nLen(aContent.getLength()); 136 137 if(nLen && sal_Unicode('#') == aContent[0]) 138 { 139 maXLink = aContent.copy(1); 140 } 141 break; 142 } 143 default: 144 { 145 break; 146 } 147 } 148 } 149 150 void SvgUseNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool /*bReferenced*/) const 151 { 152 // try to access link to content 153 const SvgNode* mpXLink = getDocument().findSvgNodeById(maXLink); 154 155 if(mpXLink) 156 { 157 // decompose childs 158 drawinglayer::primitive2d::Primitive2DSequence aNewTarget; 159 160 // todo: in case mpXLink is a SVGTokenSvg or SVGTokenSymbol the 161 // SVG docs want the getWidth() and getHeight() from this node 162 // to be valid for the subtree. 163 const_cast< SvgNode* >(mpXLink)->setAlternativeParent(this); 164 mpXLink->decomposeSvgNode(aNewTarget, true); 165 const_cast< SvgNode* >(mpXLink)->setAlternativeParent(0); 166 167 if(aNewTarget.hasElements()) 168 { 169 basegfx::B2DHomMatrix aTransform; 170 171 if(getX().isSet() || getY().isSet()) 172 { 173 aTransform.translate( 174 getX().solve(*this, xcoordinate), 175 getY().solve(*this, ycoordinate)); 176 } 177 178 if(getTransform()) 179 { 180 aTransform = *getTransform() * aTransform; 181 } 182 183 if(!aTransform.isIdentity()) 184 { 185 const drawinglayer::primitive2d::Primitive2DReference xRef( 186 new drawinglayer::primitive2d::TransformPrimitive2D( 187 aTransform, 188 aNewTarget)); 189 190 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef); 191 } 192 else 193 { 194 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget); 195 } 196 } 197 } 198 } 199 200 } // end of namespace svgreader 201 } // end of namespace svgio 202 203 ////////////////////////////////////////////////////////////////////////////// 204 // eof 205