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/svgnode.hxx> 26 #include <basegfx/polygon/b2dpolypolygontools.hxx> 27 #include <svgio/svgreader/svgdocument.hxx> 28 #include <svgio/svgreader/svgnode.hxx> 29 #include <svgio/svgreader/svgstyleattributes.hxx> 30 31 ////////////////////////////////////////////////////////////////////////////// 32 33 namespace svgio 34 { 35 namespace svgreader 36 { 37 const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const 38 { 39 return 0; 40 } 41 42 SvgNode::SvgNode( 43 SVGToken aType, 44 SvgDocument& rDocument, 45 SvgNode* pParent) 46 : maType(aType), 47 mrDocument(rDocument), 48 mpParent(pParent), 49 mpAlternativeParent(0), 50 maChildren(), 51 mpId(0), 52 mpClass(0), 53 maXmlSpace(XmlSpace_notset) 54 { 55 OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)"); 56 57 if(pParent) 58 { 59 pParent->maChildren.push_back(this); 60 } 61 else 62 { 63 #ifdef DBG_UTIL 64 if(SVGTokenSvg != getType()) 65 { 66 OSL_ENSURE(false, "No parent for this node (!)"); 67 } 68 #endif 69 } 70 } 71 72 SvgNode::~SvgNode() 73 { 74 while(maChildren.size()) 75 { 76 delete maChildren[maChildren.size() - 1]; 77 maChildren.pop_back(); 78 } 79 80 if(mpId) delete mpId; 81 if(mpClass) delete mpClass; 82 } 83 84 void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs) 85 { 86 const sal_uInt32 nAttributes(xAttribs->getLength()); 87 88 for(sal_uInt32 a(0); a < nAttributes; a++) 89 { 90 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a)); 91 92 parseAttribute(aTokenName, StrToSVGToken(aTokenName), xAttribs->getValueByIndex(a)); 93 } 94 } 95 96 void SvgNode::parseAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent) 97 { 98 switch(aSVGToken) 99 { 100 case SVGTokenId: 101 { 102 if(aContent.getLength()) 103 { 104 setId(&aContent); 105 } 106 break; 107 } 108 case SVGTokenClass: 109 { 110 if(aContent.getLength()) 111 { 112 setClass(&aContent); 113 } 114 break; 115 } 116 case SVGTokenXmlSpace: 117 { 118 if(aContent.getLength()) 119 { 120 static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default")); 121 static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve")); 122 123 if(aContent.match(aStrDefault)) 124 { 125 setXmlSpace(XmlSpace_default); 126 } 127 else if(aContent.match(aStrPreserve)) 128 { 129 setXmlSpace(XmlSpace_preserve); 130 } 131 } 132 break; 133 } 134 default: 135 { 136 break; 137 } 138 } 139 } 140 141 void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const 142 { 143 if(!bReferenced) 144 { 145 if(SVGTokenDefs == getType() || 146 SVGTokenSymbol == getType() || 147 SVGTokenClipPathNode == getType() || 148 SVGTokenMask == getType() || 149 SVGTokenMarker == getType() || 150 SVGTokenPattern == getType()) 151 { 152 // do not decompose defs or symbol nodes (these hold only style-like 153 // objects which may be used by referencing them) except when doing 154 // so controlled referenced 155 156 // also do not decompose ClipPaths and Masks. These should be embedded 157 // in a defs node (which gets not decomposed by itself), but you never 158 // know 159 160 // also not directly used are Markers and Patterns, only indirecty used 161 // by reference 162 return; 163 } 164 } 165 166 const SvgNodeVector& rChildren = getChildren(); 167 168 if(!rChildren.empty()) 169 { 170 const sal_uInt32 nCount(rChildren.size()); 171 172 for(sal_uInt32 a(0); a < nCount; a++) 173 { 174 SvgNode* pCandidate = rChildren[a]; 175 176 if(pCandidate) 177 { 178 drawinglayer::primitive2d::Primitive2DSequence aNewTarget; 179 180 pCandidate->decomposeSvgNode(aNewTarget, bReferenced); 181 182 if(aNewTarget.hasElements()) 183 { 184 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget); 185 } 186 } 187 else 188 { 189 OSL_ENSURE(false, "Null-Pointer in child node list (!)"); 190 } 191 } 192 } 193 } 194 195 const basegfx::B2DRange* SvgNode::getCurrentViewPort() const 196 { 197 if(getParent()) 198 { 199 return getParent()->getCurrentViewPort(); 200 } 201 else 202 { 203 return 0; 204 } 205 } 206 207 double SvgNode::getCurrentFontSize() const 208 { 209 if(getSvgStyleAttributes()) 210 { 211 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate); 212 } 213 else if(getParent()) 214 { 215 return getParent()->getCurrentFontSize(); 216 } 217 else 218 { 219 return 0.0; 220 } 221 } 222 223 double SvgNode::getCurrentXHeight() const 224 { 225 if(getSvgStyleAttributes()) 226 { 227 // for XHeight, use FontSize currently 228 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate); 229 } 230 else if(getParent()) 231 { 232 return getParent()->getCurrentXHeight(); 233 } 234 else 235 { 236 return 0.0; 237 } 238 } 239 240 void SvgNode::setId(const rtl::OUString* pfId) 241 { 242 if(mpId) 243 { 244 mrDocument.removeSvgNodeFromMapper(*mpId); 245 delete mpId; 246 mpId = 0; 247 } 248 249 if(pfId) 250 { 251 mpId = new rtl::OUString(*pfId); 252 mrDocument.addSvgNodeToMapper(*mpId, *this); 253 } 254 } 255 256 void SvgNode::setClass(const rtl::OUString* pfClass) 257 { 258 if(mpClass) 259 { 260 mrDocument.removeSvgNodeFromMapper(*mpClass); 261 delete mpClass; 262 mpClass = 0; 263 } 264 265 if(pfClass) 266 { 267 mpClass = new rtl::OUString(*pfClass); 268 mrDocument.addSvgNodeToMapper(*mpClass, *this); 269 } 270 } 271 272 XmlSpace SvgNode::getXmlSpace() const 273 { 274 if(maXmlSpace != XmlSpace_notset) 275 { 276 return maXmlSpace; 277 } 278 279 if(getParent()) 280 { 281 return getParent()->getXmlSpace(); 282 } 283 284 // default is XmlSpace_default 285 return XmlSpace_default; 286 } 287 288 } // end of namespace svgreader 289 } // end of namespace svgio 290 291 ////////////////////////////////////////////////////////////////////////////// 292 // eof 293