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 } 135 } 136 137 void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const 138 { 139 if(!bReferenced) 140 { 141 if(SVGTokenDefs == getType() || 142 SVGTokenSymbol == getType() || 143 SVGTokenClipPathNode == getType() || 144 SVGTokenMask == getType() || 145 SVGTokenMarker == getType() || 146 SVGTokenPattern == getType()) 147 { 148 // do not decompose defs or symbol nodes (these hold only style-like 149 // objects which may be used by referencing them) except when doing 150 // so controlled referenced 151 152 // also do not decompose ClipPaths and Masks. These should be embedded 153 // in a defs node (which gets not decomposed by itself), but you never 154 // know 155 156 // also not directly used are Markers and Patterns, only indirecty used 157 // by reference 158 return; 159 } 160 } 161 162 const SvgNodeVector& rChildren = getChildren(); 163 164 if(!rChildren.empty()) 165 { 166 const sal_uInt32 nCount(rChildren.size()); 167 168 for(sal_uInt32 a(0); a < nCount; a++) 169 { 170 SvgNode* pCandidate = rChildren[a]; 171 172 if(pCandidate) 173 { 174 drawinglayer::primitive2d::Primitive2DSequence aNewTarget; 175 176 pCandidate->decomposeSvgNode(aNewTarget, bReferenced); 177 178 if(aNewTarget.hasElements()) 179 { 180 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget); 181 } 182 } 183 else 184 { 185 OSL_ENSURE(false, "Null-Pointer in child node list (!)"); 186 } 187 } 188 } 189 } 190 191 const basegfx::B2DRange* SvgNode::getCurrentViewPort() const 192 { 193 if(getParent()) 194 { 195 return getParent()->getCurrentViewPort(); 196 } 197 else 198 { 199 return 0; 200 } 201 } 202 203 double SvgNode::getCurrentFontSize() const 204 { 205 if(getSvgStyleAttributes()) 206 { 207 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate); 208 } 209 else if(getParent()) 210 { 211 return getParent()->getCurrentFontSize(); 212 } 213 else 214 { 215 return 0.0; 216 } 217 } 218 219 double SvgNode::getCurrentXHeight() const 220 { 221 if(getSvgStyleAttributes()) 222 { 223 // for XHeight, use FontSize currently 224 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate); 225 } 226 else if(getParent()) 227 { 228 return getParent()->getCurrentXHeight(); 229 } 230 else 231 { 232 return 0.0; 233 } 234 } 235 236 void SvgNode::setId(const rtl::OUString* pfId) 237 { 238 if(mpId) 239 { 240 mrDocument.removeSvgNodeFromMapper(*mpId); 241 delete mpId; 242 mpId = 0; 243 } 244 245 if(pfId) 246 { 247 mpId = new rtl::OUString(*pfId); 248 mrDocument.addSvgNodeToMapper(*mpId, *this); 249 } 250 } 251 252 void SvgNode::setClass(const rtl::OUString* pfClass) 253 { 254 if(mpClass) 255 { 256 mrDocument.removeSvgNodeFromMapper(*mpClass); 257 delete mpClass; 258 mpClass = 0; 259 } 260 261 if(pfClass) 262 { 263 mpClass = new rtl::OUString(*pfClass); 264 mrDocument.addSvgNodeToMapper(*mpClass, *this); 265 } 266 } 267 268 XmlSpace SvgNode::getXmlSpace() const 269 { 270 if(maXmlSpace != XmlSpace_notset) 271 { 272 return maXmlSpace; 273 } 274 275 if(getParent()) 276 { 277 return getParent()->getXmlSpace(); 278 } 279 280 // default is XmlSpace_default 281 return XmlSpace_default; 282 } 283 284 } // end of namespace svgreader 285 } // end of namespace svgio 286 287 ////////////////////////////////////////////////////////////////////////////// 288 // eof 289