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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmloff.hxx" 26 #include "xmloff/MarkerStyle.hxx" 27 #include "xexptran.hxx" 28 #include <xmloff/attrlist.hxx> 29 #include <xmloff/nmspmap.hxx> 30 #include <xmloff/xmluconv.hxx> 31 #include "xmloff/xmlnmspe.hxx" 32 #include <xmloff/xmltoken.hxx> 33 #include <xmloff/xmlexp.hxx> 34 #include <xmloff/xmlimp.hxx> 35 #include <rtl/ustrbuf.hxx> 36 #include <rtl/ustring.hxx> 37 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> 38 39 using namespace ::com::sun::star; 40 using ::rtl::OUString; 41 using ::rtl::OUStringBuffer; 42 43 using namespace ::xmloff::token; 44 45 46 //------------------------------------------------------------- 47 // Import 48 //------------------------------------------------------------- 49 50 XMLMarkerStyleImport::XMLMarkerStyleImport( SvXMLImport& rImp ) 51 : rImport( rImp ) 52 { 53 } 54 55 XMLMarkerStyleImport::~XMLMarkerStyleImport() 56 { 57 } 58 59 sal_Bool XMLMarkerStyleImport::importXML( 60 const uno::Reference< xml::sax::XAttributeList >& xAttrList, 61 uno::Any& rValue, 62 OUString& rStrName ) 63 { 64 sal_Bool bHasViewBox = sal_False; 65 sal_Bool bHasPathData = sal_False; 66 OUString aDisplayName; 67 68 SdXMLImExViewBox* pViewBox = NULL; 69 70 SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap(); 71 SvXMLUnitConverter& rUnitConverter = rImport.GetMM100UnitConverter(); 72 73 OUString strPathData; 74 75 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 76 for( sal_Int16 i = 0; i < nAttrCount; i++ ) 77 { 78 OUString aStrFullAttrName = xAttrList->getNameByIndex( i ); 79 OUString aStrAttrName; 80 rNamespaceMap.GetKeyByAttrName( aStrFullAttrName, &aStrAttrName ); 81 OUString aStrValue = xAttrList->getValueByIndex( i ); 82 83 if( IsXMLToken( aStrAttrName, XML_NAME ) ) 84 { 85 rStrName = aStrValue; 86 } 87 else if( IsXMLToken( aStrAttrName, XML_DISPLAY_NAME ) ) 88 { 89 aDisplayName = aStrValue; 90 } 91 else if( IsXMLToken( aStrAttrName, XML_VIEWBOX ) ) 92 { 93 pViewBox = new SdXMLImExViewBox( aStrValue, rUnitConverter ); 94 bHasViewBox = sal_True; 95 96 } 97 else if( IsXMLToken( aStrAttrName, XML_D ) ) 98 { 99 strPathData = aStrValue; 100 bHasPathData = sal_True; 101 } 102 } 103 104 if( bHasViewBox && bHasPathData ) 105 { 106 SdXMLImExSvgDElement aPoints(strPathData, *pViewBox, awt::Point( 0, 0 ), 107 awt::Size( pViewBox->GetWidth(), pViewBox->GetHeight() ), 108 rUnitConverter ); 109 110 if(aPoints.IsCurve()) 111 { 112 drawing::PolyPolygonBezierCoords aSourcePolyPolygon( 113 aPoints.GetPointSequenceSequence(), 114 aPoints.GetFlagSequenceSequence()); 115 rValue <<= aSourcePolyPolygon; 116 } 117 else 118 { 119 drawing::PolyPolygonBezierCoords aSourcePolyPolygon; 120 aSourcePolyPolygon.Coordinates = aPoints.GetPointSequenceSequence(); 121 aSourcePolyPolygon.Flags.realloc(aSourcePolyPolygon.Coordinates.getLength()); 122 123 // Zeiger auf innere sequences holen 124 const drawing::PointSequence* pInnerSequence = aSourcePolyPolygon.Coordinates.getConstArray(); 125 drawing::FlagSequence* pInnerSequenceFlags = aSourcePolyPolygon.Flags.getArray(); 126 127 for(sal_Int32 a(0); a < aSourcePolyPolygon.Coordinates.getLength(); a++) 128 { 129 pInnerSequenceFlags->realloc(pInnerSequence->getLength()); 130 drawing::PolygonFlags* pPolyFlags = pInnerSequenceFlags->getArray(); 131 132 for(sal_Int32 b(0); b < pInnerSequence->getLength(); b++) 133 *pPolyFlags++ = drawing::PolygonFlags_NORMAL; 134 135 // next run 136 pInnerSequence++; 137 pInnerSequenceFlags++; 138 } 139 140 rValue <<= aSourcePolyPolygon; 141 } 142 143 if( aDisplayName.getLength() ) 144 { 145 rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName, 146 aDisplayName ); 147 rStrName = aDisplayName; 148 } 149 150 } 151 152 if( pViewBox ) 153 delete pViewBox; 154 155 return bHasViewBox && bHasPathData; 156 } 157 158 159 //------------------------------------------------------------- 160 // Export 161 //------------------------------------------------------------- 162 163 #ifndef SVX_LIGHT 164 165 XMLMarkerStyleExport::XMLMarkerStyleExport( SvXMLExport& rExp ) 166 : rExport( rExp ) 167 { 168 } 169 170 XMLMarkerStyleExport::~XMLMarkerStyleExport() 171 { 172 } 173 174 sal_Bool XMLMarkerStyleExport::exportXML( 175 const OUString& rStrName, 176 const uno::Any& rValue ) 177 { 178 sal_Bool bRet(sal_False); 179 180 if(rStrName.getLength()) 181 { 182 drawing::PolyPolygonBezierCoords aBezier; 183 184 if(rValue >>= aBezier) 185 { 186 OUString aStrValue; 187 OUStringBuffer aOut; 188 189 ///////////////// 190 // Name 191 sal_Bool bEncoded = sal_False; 192 OUString aStrName( rStrName ); 193 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, 194 rExport.EncodeStyleName( aStrName, 195 &bEncoded ) ); 196 if( bEncoded ) 197 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, 198 aStrName ); 199 200 ///////////////// 201 // Viewbox (viewBox="0 0 1500 1000") 202 sal_Int32 nMinX(0x7fffffff); 203 sal_Int32 nMaxX(0x80000000); 204 sal_Int32 nMinY(0x7fffffff); 205 sal_Int32 nMaxY(0x80000000); 206 sal_Int32 nOuterCnt(aBezier.Coordinates.getLength()); 207 drawing::PointSequence* pOuterSequence = aBezier.Coordinates.getArray(); 208 sal_Int32 a, b; 209 sal_Bool bClosed(sal_False); 210 211 for (a = 0; a < nOuterCnt; a++) 212 { 213 drawing::PointSequence* pSequence = pOuterSequence++; 214 const awt::Point *pPoints = pSequence->getConstArray(); 215 sal_Int32 nPointCount(pSequence->getLength()); 216 217 if(nPointCount) 218 { 219 const awt::Point aStart = pPoints[0]; 220 const awt::Point aEnd = pPoints[nPointCount - 1]; 221 222 if(aStart.X == aEnd.X && aStart.Y == aEnd.Y) 223 { 224 bClosed = sal_True; 225 } 226 } 227 228 for (b = 0; b < nPointCount; b++) 229 { 230 const awt::Point aPoint = pPoints[b]; 231 232 if( aPoint.X < nMinX ) 233 nMinX = aPoint.X; 234 235 if( aPoint.X > nMaxX ) 236 nMaxX = aPoint.X; 237 238 if( aPoint.Y < nMinY ) 239 nMinY = aPoint.Y; 240 241 if( aPoint.Y > nMaxY ) 242 nMaxY = aPoint.Y; 243 } 244 } 245 246 sal_Int32 nDifX(nMaxX - nMinX); 247 sal_Int32 nDifY(nMaxY - nMinY); 248 249 SdXMLImExViewBox aViewBox( 0, 0, nDifX, nDifY ); 250 rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() ); 251 252 ///////////////// 253 // Pathdata 254 pOuterSequence = aBezier.Coordinates.getArray(); 255 drawing::FlagSequence* pOuterFlags = aBezier.Flags.getArray(); 256 SdXMLImExSvgDElement aSvgDElement(aViewBox); 257 258 for (a = 0; a < nOuterCnt; a++) 259 { 260 drawing::PointSequence* pSequence = pOuterSequence++; 261 drawing::FlagSequence* pFlags = pOuterFlags++; 262 263 aSvgDElement.AddPolygon(pSequence, pFlags, 264 awt::Point( 0, 0 ), 265 awt::Size( aViewBox.GetWidth(), aViewBox.GetHeight() ), 266 bClosed); 267 } 268 269 // write point array 270 rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString()); 271 272 ///////////////// 273 // Do Write 274 SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, 275 sal_True, sal_False ); 276 } 277 } 278 279 return bRet; 280 } 281 282 #endif // #ifndef SVX_LIGHT 283