svgnode.cxx (9d56236f) | svgnode.cxx (9d01bcde) |
---|---|
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 --- 33 unchanged lines hidden (view full) --- 42 return true; 43 } 44 45 const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const 46 { 47 return 0; 48 } 49 | 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 --- 33 unchanged lines hidden (view full) --- 42 return true; 43 } 44 45 const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const 46 { 47 return 0; 48 } 49 |
50 const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const | 50 void SvgNode::fillCssStyleVector(const rtl::OUString& rClassStr) |
51 { | 51 { |
52 if(maCssStyleVector.empty()) // #120435# Evaluate for CSS styles only once, this cannot change | 52 OSL_ENSURE(!mbCssStyleVectorBuilt, "OOps, fillCssStyleVector called double ?!?"); 53 mbCssStyleVectorBuilt = true; 54 55 // #125293# If we have CssStyles we need to buuild a linked list of SvgStyleAttributes 56 // which represent this for the current object. There are various methods to 57 // specify CssStyles which need to be taken into account in a given order: 58 // - local CssStyle (independent from global CssStyles at SvgDocument) 59 // - 'id' CssStyle 60 // - 'class' CssStyle(s) 61 // - type-dependent elements (e..g. 'rect' for all rect elements) 62 // - local attributes (rOriginal) 63 // - inherited attributes (up the hierarchy) 64 // The first four will be collected in maCssStyleVector for the current element 65 // (once, this will not change) and be linked in the needed order using the 66 // get/setCssStyleParent at the SvgStyleAttributes which will be used preferred in 67 // member evaluation over the existing parent hierarchy 68 69 // check for local CssStyle with highest priority 70 if(mpLocalCssStyle) |
53 { | 71 { |
54 const SvgDocument& rDocument = getDocument(); | 72 // if we have one, use as first entry 73 maCssStyleVector.push_back(mpLocalCssStyle); 74 } |
55 | 75 |
56 if(rDocument.hasSvgStyleAttributesById()) | 76 const SvgDocument& rDocument = getDocument(); 77 78 if(rDocument.hasSvgStyleAttributesById()) 79 { 80 // check for 'id' references 81 if(getId()) |
57 { | 82 { |
58 // #125293# If we have CssStyles we need to buuild a linked list of SvgStyleAttributes 59 // which represent this for the current object. There are various methods to 60 // specify CssStyles which need to be taken into account in a given order: 61 // - 'id' element 62 // - 'class' element(s) 63 // - type-dependent elements (e..g. 'rect' for all rect elements) 64 // - local firect attributes (rOriginal) 65 // - inherited attributes (up the hierarchy) 66 // The first three will be collected in maCssStyleVector for the current element 67 // (once, this will not change) and be linked in the needed order using the 68 // get/setCssStyleParent at the SvgStyleAttributes which will be used preferred in 69 // member evaluation over the existing parent hierarchy | 83 // concatenate combined style name during search for CSS style equal to Id 84 // when travelling over node parents 85 rtl::OUString aConcatenatedStyleName; 86 const SvgNode* pCurrent = this; 87 const SvgStyleAttributes* pNew = 0; |
70 | 88 |
71 // check for 'id' references 72 if(getId()) | 89 while(!pNew && pCurrent) |
73 { | 90 { |
74 // search for CSS style equal to Id 75 const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId()); | 91 if(pCurrent->getId()) 92 { 93 aConcatenatedStyleName = *pCurrent->getId() + aConcatenatedStyleName; 94 } |
76 | 95 |
77 if(pNew) | 96 if(aConcatenatedStyleName.getLength()) |
78 { | 97 { |
79 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); | 98 pNew = rDocument.findSvgStyleAttributesById(aConcatenatedStyleName); |
80 } | 99 } |
100 101 pCurrent = pCurrent->getParent(); |
|
81 } 82 | 102 } 103 |
83 // check for 'class' references 84 if(getClass()) | 104 if(pNew) |
85 { | 105 { |
86 // find all referenced CSS styles, a list of entries is allowed 87 const rtl::OUString* pClassList = getClass(); 88 const sal_Int32 nLen(pClassList->getLength()); 89 sal_Int32 nPos(0); 90 const SvgStyleAttributes* pNew = 0; | 106 maCssStyleVector.push_back(pNew); 107 } 108 } |
91 | 109 |
92 skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); | 110 // check for 'class' references 111 if(getClass()) 112 { 113 // find all referenced CSS styles (a list of entries is allowed) 114 const rtl::OUString* pClassList = getClass(); 115 const sal_Int32 nLen(pClassList->getLength()); 116 sal_Int32 nPos(0); 117 const SvgStyleAttributes* pNew = 0; |
93 | 118 |
94 while(nPos < nLen) 95 { 96 rtl::OUStringBuffer aTokenValue; | 119 skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); |
97 | 120 |
98 copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen); 99 skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); | 121 while(nPos < nLen) 122 { 123 rtl::OUStringBuffer aTokenValue; |
100 | 124 |
101 rtl::OUString aId(rtl::OUString::createFromAscii(".")); 102 const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); | 125 copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen); 126 skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); |
103 | 127 |
104 // look for CSS style common to token 105 aId = aId + aOUTokenValue; 106 pNew = rDocument.findSvgStyleAttributesById(aId); | 128 rtl::OUString aId(rtl::OUString::createFromAscii(".")); 129 const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); |
107 | 130 |
108 if(!pNew && rClassStr.getLength()) 109 { 110 // look for CSS style common to class.token 111 aId = rClassStr + aId; | 131 // look for CSS style common to token 132 aId = aId + aOUTokenValue; 133 pNew = rDocument.findSvgStyleAttributesById(aId); |
112 | 134 |
113 pNew = rDocument.findSvgStyleAttributesById(aId); 114 } | 135 if(!pNew && rClassStr.getLength()) 136 { 137 // look for CSS style common to class.token 138 aId = rClassStr + aId; |
115 | 139 |
116 if(pNew) 117 { 118 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); 119 } | 140 pNew = rDocument.findSvgStyleAttributesById(aId); |
120 } | 141 } |
121 } | |
122 | 142 |
123 // check for class-dependent references to CssStyles 124 if(rClassStr.getLength()) 125 { 126 // search for CSS style equal to class type 127 const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr); 128 | |
129 if(pNew) 130 { | 143 if(pNew) 144 { |
131 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); | 145 maCssStyleVector.push_back(pNew); |
132 } 133 } 134 } | 146 } 147 } 148 } |
149 150 // check for class-dependent references to CssStyles 151 if(rClassStr.getLength()) 152 { 153 // search for CSS style equal to class type 154 const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr); 155 156 if(pNew) 157 { 158 maCssStyleVector.push_back(pNew); 159 } 160 } |
|
135 } | 161 } |
162 } |
|
136 | 163 |
164 const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const 165 { 166 if(!mbCssStyleVectorBuilt) 167 { 168 // build needed CssStyleVector for local node 169 const_cast< SvgNode* >(this)->fillCssStyleVector(rClassStr); 170 } 171 |
|
137 if(maCssStyleVector.empty()) 138 { | 172 if(maCssStyleVector.empty()) 173 { |
139 // return original if no CssStlyes found | 174 // return given original if no CssStlyes found |
140 return &rOriginal; 141 } 142 else 143 { 144 // #125293# rOriginal will be the last element in the linked list; use no CssStyleParent 145 // there (reset it) to ensure that the parent hierarchy will be used when it's base 146 // is referenced. This new chaning inserts the CssStyles before the original style, 147 // this makes the whole process much safer since the original style when used will --- 40 unchanged lines hidden (view full) --- 188 mrDocument(rDocument), 189 mpParent(pParent), 190 mpAlternativeParent(0), 191 maChildren(), 192 mpId(0), 193 mpClass(0), 194 maXmlSpace(XmlSpace_notset), 195 maDisplay(Display_inline), | 175 return &rOriginal; 176 } 177 else 178 { 179 // #125293# rOriginal will be the last element in the linked list; use no CssStyleParent 180 // there (reset it) to ensure that the parent hierarchy will be used when it's base 181 // is referenced. This new chaning inserts the CssStyles before the original style, 182 // this makes the whole process much safer since the original style when used will --- 40 unchanged lines hidden (view full) --- 223 mrDocument(rDocument), 224 mpParent(pParent), 225 mpAlternativeParent(0), 226 maChildren(), 227 mpId(0), 228 mpClass(0), 229 maXmlSpace(XmlSpace_notset), 230 maDisplay(Display_inline), |
196 maCssStyleVector() | 231 maCssStyleVector(), 232 mpLocalCssStyle(0), 233 mbCssStyleVectorBuilt(false) |
197 { 198 OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)"); 199 200 if(pParent) 201 { 202 pParent->maChildren.push_back(this); 203 } 204 else --- 10 unchanged lines hidden (view full) --- 215 SvgNode::~SvgNode() 216 { 217 while(maChildren.size()) 218 { 219 delete maChildren[maChildren.size() - 1]; 220 maChildren.pop_back(); 221 } 222 | 234 { 235 OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)"); 236 237 if(pParent) 238 { 239 pParent->maChildren.push_back(this); 240 } 241 else --- 10 unchanged lines hidden (view full) --- 252 SvgNode::~SvgNode() 253 { 254 while(maChildren.size()) 255 { 256 delete maChildren[maChildren.size() - 1]; 257 maChildren.pop_back(); 258 } 259 |
223 if(mpId) delete mpId; 224 if(mpClass) delete mpClass; | 260 if(mpId) 261 { 262 delete mpId; 263 } 264 265 if(mpClass) 266 { 267 delete mpClass; 268 } 269 270 if(mpLocalCssStyle) 271 { 272 delete mpLocalCssStyle; 273 } |
225 } 226 | 274 } 275 |
276 void SvgNode::readLocalCssStyle(const rtl::OUString& aContent) 277 { 278 if(!mpLocalCssStyle) 279 { 280 // create LocalCssStyle if needed but not yet added 281 mpLocalCssStyle = new SvgStyleAttributes(*this); 282 } 283 else 284 { 285 // 2nd fill would be an error 286 OSL_ENSURE(false, "Svg node has two local CssStyles, this may lead to problems (!)"); 287 } 288 289 if(mpLocalCssStyle) 290 { 291 // parse and set values to it 292 mpLocalCssStyle->readStyle(aContent); 293 } 294 else 295 { 296 OSL_ENSURE(false, "Could not get/create a local CssStyle for a node (!)"); 297 } 298 } 299 |
|
227 void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs) 228 { | 300 void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs) 301 { |
302 // no longer need to pre-sort moving 'style' entries to the back so that 303 // values get overwritten - that was the previous, not complete solution for 304 // handling the priorities between svg and Css properties |
|
229 const sal_uInt32 nAttributes(xAttribs->getLength()); | 305 const sal_uInt32 nAttributes(xAttribs->getLength()); |
230 // #122522# SVG defines that 'In general, this means that the presentation attributes have 231 // lower priority than other CSS style rules specified in author style sheets or �style� 232 // attributes.' in http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes 233 // (6.4 Specifying properties using the presentation attributes SVG 1.1). That means that 234 // e.g. font-size will appear as presentation attribute and CSS style attribute. In these 235 // cases, CSS style attributes need to have precedence. To do so it is possible to create 236 // a proirity system for all properties of a shape, but it will also work to parse the 237 // presentation attributes of type 'style' last, so they will overwrite the less-prioritized 238 // already interpreted ones. Thus, remember SVGTokenStyle entries and parse them last. 239 // To make this work it is required that parseAttribute is only called by parseAttributes 240 // which is the case. 241 std::vector< sal_uInt32 > aSVGTokenStyleIndexes; | |
242 243 for(sal_uInt32 a(0); a < nAttributes; a++) 244 { 245 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a)); 246 const SVGToken aSVGToken(StrToSVGToken(aTokenName)); 247 | 306 307 for(sal_uInt32 a(0); a < nAttributes; a++) 308 { 309 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a)); 310 const SVGToken aSVGToken(StrToSVGToken(aTokenName)); 311 |
248 if(SVGTokenStyle == aSVGToken) 249 { 250 // #122522# remember SVGTokenStyle entry 251 aSVGTokenStyleIndexes.push_back(a); 252 } 253 else 254 { 255 parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a)); 256 } | 312 parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a)); |
257 } | 313 } |
258 259 // #122522# parse SVGTokenStyle entries last to override already interpreted 260 // 'presentation attributes' of potenially the same type 261 for(sal_uInt32 b(0); b < aSVGTokenStyleIndexes.size(); b++) 262 { 263 const sal_uInt32 nSVGTokenStyleIndex(aSVGTokenStyleIndexes[b]); 264 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(nSVGTokenStyleIndex)); 265 266 parseAttribute(aTokenName, SVGTokenStyle, xAttribs->getValueByIndex(nSVGTokenStyleIndex)); 267 } | |
268 } 269 270 Display getDisplayFromContent(const rtl::OUString& aContent) 271 { 272 if(aContent.getLength()) 273 { 274 static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline")); 275 static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block")); --- 352 unchanged lines hidden --- | 314 } 315 316 Display getDisplayFromContent(const rtl::OUString& aContent) 317 { 318 if(aContent.getLength()) 319 { 320 static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline")); 321 static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block")); --- 352 unchanged lines hidden --- |