1*63bba73cSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*63bba73cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*63bba73cSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*63bba73cSAndrew Rist * distributed with this work for additional information 6*63bba73cSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*63bba73cSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*63bba73cSAndrew Rist * "License"); you may not use this file except in compliance 9*63bba73cSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*63bba73cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*63bba73cSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*63bba73cSAndrew Rist * software distributed under the License is distributed on an 15*63bba73cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*63bba73cSAndrew Rist * KIND, either express or implied. See the License for the 17*63bba73cSAndrew Rist * specific language governing permissions and limitations 18*63bba73cSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*63bba73cSAndrew Rist *************************************************************/ 21*63bba73cSAndrew Rist 22*63bba73cSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_xmloff.hxx" 26cdf0e10cSrcweir #include "xexptran.hxx" 27cdf0e10cSrcweir #include <tools/debug.hxx> 28cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 29cdf0e10cSrcweir #include <xmloff/xmluconv.hxx> 30cdf0e10cSrcweir #include <tools/gen.hxx> 31cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx> 32cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 33cdf0e10cSrcweir #include <basegfx/tuple/b3dtuple.hxx> 34cdf0e10cSrcweir #include <basegfx/matrix/b3dhommatrix.hxx> 35cdf0e10cSrcweir #include <tools/string.hxx> 36cdf0e10cSrcweir 37cdf0e10cSrcweir using ::rtl::OUString; 38cdf0e10cSrcweir using ::rtl::OUStringBuffer; 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace ::com::sun::star; 41cdf0e10cSrcweir 42cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 43cdf0e10cSrcweir // Defines 44cdf0e10cSrcweir 45cdf0e10cSrcweir #define BORDER_INTEGERS_ARE_EQUAL (4) 46cdf0e10cSrcweir 47cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 48cdf0e10cSrcweir // Predeclarations 49cdf0e10cSrcweir 50cdf0e10cSrcweir void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen); 51cdf0e10cSrcweir void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection); 52cdf0e10cSrcweir 53cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 54cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 55cdf0e10cSrcweir // parsing help functions for simple chars 56cdf0e10cSrcweir void Imp_SkipSpaces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir while(rPos < nLen 59cdf0e10cSrcweir && sal_Unicode(' ') == rStr[rPos]) 60cdf0e10cSrcweir rPos++; 61cdf0e10cSrcweir } 62cdf0e10cSrcweir 63cdf0e10cSrcweir void Imp_SkipSpacesAndOpeningBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen) 64cdf0e10cSrcweir { 65cdf0e10cSrcweir while(rPos < nLen 66cdf0e10cSrcweir && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode('(') == rStr[rPos])) 67cdf0e10cSrcweir rPos++; 68cdf0e10cSrcweir } 69cdf0e10cSrcweir 70cdf0e10cSrcweir void Imp_SkipSpacesAndCommas(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir while(rPos < nLen 73cdf0e10cSrcweir && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(',') == rStr[rPos])) 74cdf0e10cSrcweir rPos++; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir void Imp_SkipSpacesAndClosingBraces(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir while(rPos < nLen 80cdf0e10cSrcweir && (sal_Unicode(' ') == rStr[rPos] || sal_Unicode(')') == rStr[rPos])) 81cdf0e10cSrcweir rPos++; 82cdf0e10cSrcweir } 83cdf0e10cSrcweir 84cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 85cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 86cdf0e10cSrcweir // parsing help functions for integer numbers 87cdf0e10cSrcweir 88cdf0e10cSrcweir bool Imp_IsOnNumberChar(const OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir sal_Unicode aChar(rStr[nPos]); 91cdf0e10cSrcweir 92cdf0e10cSrcweir if((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) 93cdf0e10cSrcweir || (bSignAllowed && sal_Unicode('+') == aChar) 94cdf0e10cSrcweir || (bSignAllowed && sal_Unicode('-') == aChar) 95cdf0e10cSrcweir ) 96cdf0e10cSrcweir return true; 97cdf0e10cSrcweir return false; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir bool Imp_IsOnUnitChar(const OUString& rStr, const sal_Int32 nPos) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir sal_Unicode aChar(rStr[nPos]); 103cdf0e10cSrcweir 104cdf0e10cSrcweir if((sal_Unicode('a') <= aChar && sal_Unicode('z') >= aChar) 105cdf0e10cSrcweir || (sal_Unicode('A') <= aChar && sal_Unicode('Z') >= aChar) 106cdf0e10cSrcweir || sal_Unicode('%') == aChar 107cdf0e10cSrcweir ) 108cdf0e10cSrcweir return true; 109cdf0e10cSrcweir return false; 110cdf0e10cSrcweir } 111cdf0e10cSrcweir 112cdf0e10cSrcweir void Imp_SkipNumber(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir bool bSignAllowed(true); 115cdf0e10cSrcweir 116cdf0e10cSrcweir while(rPos < nLen && Imp_IsOnNumberChar(rStr, rPos, bSignAllowed)) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir bSignAllowed = false; 119cdf0e10cSrcweir rPos++; 120cdf0e10cSrcweir } 121cdf0e10cSrcweir } 122cdf0e10cSrcweir 123cdf0e10cSrcweir void Imp_SkipNumberAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos, 124cdf0e10cSrcweir const sal_Int32 nLen) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir Imp_SkipNumber(rStr, rPos, nLen); 127cdf0e10cSrcweir Imp_SkipSpacesAndCommas(rStr, rPos, nLen); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir // #100617# Allow to skip doubles, too. 131cdf0e10cSrcweir void Imp_SkipDoubleAndSpacesAndCommas(const OUString& rStr, sal_Int32& rPos, 132cdf0e10cSrcweir const sal_Int32 nLen) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir Imp_SkipDouble(rStr, rPos, nLen); 135cdf0e10cSrcweir Imp_SkipSpacesAndCommas(rStr, rPos, nLen); 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir void Imp_PutNumberChar(OUString& rStr, sal_Int32 nValue) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir OUStringBuffer sStringBuffer; 141cdf0e10cSrcweir SvXMLUnitConverter::convertNumber(sStringBuffer, nValue); 142cdf0e10cSrcweir rStr += OUString(sStringBuffer.makeStringAndClear()); 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145cdf0e10cSrcweir void Imp_PutNumberCharWithSpace(OUString& rStr, sal_Int32 nValue) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir const sal_Int32 aLen(rStr.getLength()); 148cdf0e10cSrcweir if(aLen) 149cdf0e10cSrcweir if(Imp_IsOnNumberChar(rStr, aLen - 1, false) && nValue >= 0) 150cdf0e10cSrcweir rStr += String(sal_Unicode(' ')); 151cdf0e10cSrcweir Imp_PutNumberChar(rStr, nValue); 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 155cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 156cdf0e10cSrcweir // parsing help functions for double numbers 157cdf0e10cSrcweir 158cdf0e10cSrcweir void Imp_SkipDouble(const OUString& rStr, sal_Int32& rPos, const sal_Int32) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir sal_Unicode aChar(rStr[rPos]); 161cdf0e10cSrcweir 162cdf0e10cSrcweir if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) 163cdf0e10cSrcweir aChar = rStr[++rPos]; 164cdf0e10cSrcweir 165cdf0e10cSrcweir while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) 166cdf0e10cSrcweir || sal_Unicode('.') == aChar) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir aChar = rStr[++rPos]; 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir aChar = rStr[++rPos]; 174cdf0e10cSrcweir 175cdf0e10cSrcweir if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) 176cdf0e10cSrcweir aChar = rStr[++rPos]; 177cdf0e10cSrcweir 178cdf0e10cSrcweir while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir aChar = rStr[++rPos]; 181cdf0e10cSrcweir } 182cdf0e10cSrcweir } 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir double Imp_GetDoubleChar(const OUString& rStr, sal_Int32& rPos, const sal_Int32 nLen, 186cdf0e10cSrcweir const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir sal_Unicode aChar(rStr[rPos]); 189cdf0e10cSrcweir OUStringBuffer sNumberString; 190cdf0e10cSrcweir 191cdf0e10cSrcweir if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir sNumberString.append(rStr[rPos]); 194cdf0e10cSrcweir aChar = rStr[++rPos]; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) 198cdf0e10cSrcweir || sal_Unicode('.') == aChar) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir sNumberString.append(rStr[rPos]); 201cdf0e10cSrcweir aChar = rStr[++rPos]; 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir sNumberString.append(rStr[rPos]); 207cdf0e10cSrcweir aChar = rStr[++rPos]; 208cdf0e10cSrcweir 209cdf0e10cSrcweir if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar) 210cdf0e10cSrcweir { 211cdf0e10cSrcweir sNumberString.append(rStr[rPos]); 212cdf0e10cSrcweir aChar = rStr[++rPos]; 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) 216cdf0e10cSrcweir { 217cdf0e10cSrcweir sNumberString.append(rStr[rPos]); 218cdf0e10cSrcweir aChar = rStr[++rPos]; 219cdf0e10cSrcweir } 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir if(bLookForUnits) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir Imp_SkipSpaces(rStr, rPos, nLen); 225cdf0e10cSrcweir while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos)) 226cdf0e10cSrcweir sNumberString.append(rStr[rPos++]); 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229cdf0e10cSrcweir if(sNumberString.getLength()) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir if(bLookForUnits) 232cdf0e10cSrcweir rConv.convertDouble(fRetval, sNumberString.makeStringAndClear(), true); 233cdf0e10cSrcweir else 234cdf0e10cSrcweir rConv.convertDouble(fRetval, sNumberString.makeStringAndClear()); 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir return fRetval; 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir void Imp_PutDoubleChar(OUString& rStr, const SvXMLUnitConverter& rConv, double fValue, 241cdf0e10cSrcweir bool bConvertUnits = false) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir OUStringBuffer sStringBuffer; 244cdf0e10cSrcweir 245cdf0e10cSrcweir if(bConvertUnits) 246cdf0e10cSrcweir rConv.convertDouble(sStringBuffer, fValue, true); 247cdf0e10cSrcweir else 248cdf0e10cSrcweir rConv.convertDouble(sStringBuffer, fValue); 249cdf0e10cSrcweir 250cdf0e10cSrcweir rStr += OUString(sStringBuffer.makeStringAndClear()); 251cdf0e10cSrcweir } 252cdf0e10cSrcweir 253cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 254cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 255cdf0e10cSrcweir // base class of all 2D transform objects 256cdf0e10cSrcweir 257cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DBase 258cdf0e10cSrcweir { 259cdf0e10cSrcweir sal_uInt16 mnType; 260cdf0e10cSrcweir ImpSdXMLExpTransObj2DBase(sal_uInt16 nType) 261cdf0e10cSrcweir : mnType(nType) {} 262cdf0e10cSrcweir }; 263cdf0e10cSrcweir 264cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 265cdf0e10cSrcweir // possible object types for 2D 266cdf0e10cSrcweir 267cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE 0x0000 268cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SCALE 0x0001 269cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE 0x0002 270cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX 0x0003 271cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY 0x0004 272cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX 0x0005 273cdf0e10cSrcweir 274cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 275cdf0e10cSrcweir // classes of objects, different sizes 276cdf0e10cSrcweir 277cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase 278cdf0e10cSrcweir { 279cdf0e10cSrcweir double mfRotate; 280cdf0e10cSrcweir ImpSdXMLExpTransObj2DRotate(double fVal) 281cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE), mfRotate(fVal) {} 282cdf0e10cSrcweir }; 283cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase 284cdf0e10cSrcweir { 285cdf0e10cSrcweir ::basegfx::B2DTuple maScale; 286cdf0e10cSrcweir ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew) 287cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE), maScale(rNew) {} 288cdf0e10cSrcweir }; 289cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase 290cdf0e10cSrcweir { 291cdf0e10cSrcweir ::basegfx::B2DTuple maTranslate; 292cdf0e10cSrcweir ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew) 293cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE), maTranslate(rNew) {} 294cdf0e10cSrcweir }; 295cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase 296cdf0e10cSrcweir { 297cdf0e10cSrcweir double mfSkewX; 298cdf0e10cSrcweir ImpSdXMLExpTransObj2DSkewX(double fVal) 299cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX), mfSkewX(fVal) {} 300cdf0e10cSrcweir }; 301cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase 302cdf0e10cSrcweir { 303cdf0e10cSrcweir double mfSkewY; 304cdf0e10cSrcweir ImpSdXMLExpTransObj2DSkewY(double fVal) 305cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY), mfSkewY(fVal) {} 306cdf0e10cSrcweir }; 307cdf0e10cSrcweir struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase 308cdf0e10cSrcweir { 309cdf0e10cSrcweir ::basegfx::B2DHomMatrix maMatrix; 310cdf0e10cSrcweir ImpSdXMLExpTransObj2DMatrix(const ::basegfx::B2DHomMatrix& rNew) 311cdf0e10cSrcweir : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX), maMatrix(rNew) {} 312cdf0e10cSrcweir }; 313cdf0e10cSrcweir 314cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 315cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 316cdf0e10cSrcweir // delete all entries in list 317cdf0e10cSrcweir 318cdf0e10cSrcweir void SdXMLImExTransform2D::EmptyList() 319cdf0e10cSrcweir { 320cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 321cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 322cdf0e10cSrcweir { 323cdf0e10cSrcweir ImpSdXMLExpTransObj2DBase* pObj = maList[a]; 324cdf0e10cSrcweir 325cdf0e10cSrcweir switch(pObj->mnType) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE : 328cdf0e10cSrcweir { 329cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DRotate*)pObj; 330cdf0e10cSrcweir break; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SCALE : 333cdf0e10cSrcweir { 334cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DScale*)pObj; 335cdf0e10cSrcweir break; 336cdf0e10cSrcweir } 337cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE : 338cdf0e10cSrcweir { 339cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DTranslate*)pObj; 340cdf0e10cSrcweir break; 341cdf0e10cSrcweir } 342cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX : 343cdf0e10cSrcweir { 344cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DSkewX*)pObj; 345cdf0e10cSrcweir break; 346cdf0e10cSrcweir } 347cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY : 348cdf0e10cSrcweir { 349cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DSkewY*)pObj; 350cdf0e10cSrcweir break; 351cdf0e10cSrcweir } 352cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX : 353cdf0e10cSrcweir { 354cdf0e10cSrcweir delete (ImpSdXMLExpTransObj2DMatrix*)pObj; 355cdf0e10cSrcweir break; 356cdf0e10cSrcweir } 357cdf0e10cSrcweir default : 358cdf0e10cSrcweir { 359cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform2D: impossible entry!"); 360cdf0e10cSrcweir break; 361cdf0e10cSrcweir } 362cdf0e10cSrcweir } 363cdf0e10cSrcweir } 364cdf0e10cSrcweir 365cdf0e10cSrcweir maList.clear(); 366cdf0e10cSrcweir } 367cdf0e10cSrcweir 368cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 369cdf0e10cSrcweir // add members 370cdf0e10cSrcweir 371cdf0e10cSrcweir void SdXMLImExTransform2D::AddRotate(double fNew) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir if(fNew != 0.0) 374cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DRotate(fNew)); 375cdf0e10cSrcweir } 376cdf0e10cSrcweir 377cdf0e10cSrcweir void SdXMLImExTransform2D::AddScale(const ::basegfx::B2DTuple& rNew) 378cdf0e10cSrcweir { 379cdf0e10cSrcweir if(1.0 != rNew.getX() || 1.0 != rNew.getY()) 380cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DScale(rNew)); 381cdf0e10cSrcweir } 382cdf0e10cSrcweir 383cdf0e10cSrcweir void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew) 384cdf0e10cSrcweir { 385cdf0e10cSrcweir if(!rNew.equalZero()) 386cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DTranslate(rNew)); 387cdf0e10cSrcweir } 388cdf0e10cSrcweir 389cdf0e10cSrcweir void SdXMLImExTransform2D::AddSkewX(double fNew) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir if(fNew != 0.0) 392cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fNew)); 393cdf0e10cSrcweir } 394cdf0e10cSrcweir 395cdf0e10cSrcweir void SdXMLImExTransform2D::AddSkewY(double fNew) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir if(fNew != 0.0) 398cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fNew)); 399cdf0e10cSrcweir } 400cdf0e10cSrcweir 401cdf0e10cSrcweir void SdXMLImExTransform2D::AddMatrix(const ::basegfx::B2DHomMatrix& rNew) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir if(!rNew.isIdentity()) 404cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DMatrix(rNew)); 405cdf0e10cSrcweir } 406cdf0e10cSrcweir 407cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 408cdf0e10cSrcweir // gen string for export 409cdf0e10cSrcweir const OUString& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter& rConv) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir OUString aNewString; 412cdf0e10cSrcweir OUString aClosingBrace(sal_Unicode(')')); 413cdf0e10cSrcweir OUString aEmptySpace(sal_Unicode(' ')); 414cdf0e10cSrcweir 415cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 416cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 417cdf0e10cSrcweir { 418cdf0e10cSrcweir ImpSdXMLExpTransObj2DBase* pObj = maList[a]; 419cdf0e10cSrcweir switch(pObj->mnType) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE : 422cdf0e10cSrcweir { 423cdf0e10cSrcweir aNewString += OUString::createFromAscii("rotate ("); 424cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate); 425cdf0e10cSrcweir aNewString += aClosingBrace; 426cdf0e10cSrcweir break; 427cdf0e10cSrcweir } 428cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SCALE : 429cdf0e10cSrcweir { 430cdf0e10cSrcweir aNewString += OUString::createFromAscii("scale ("); 431cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getX()); 432cdf0e10cSrcweir aNewString += aEmptySpace; 433cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale.getY()); 434cdf0e10cSrcweir aNewString += aClosingBrace; 435cdf0e10cSrcweir break; 436cdf0e10cSrcweir } 437cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE : 438cdf0e10cSrcweir { 439cdf0e10cSrcweir aNewString += OUString::createFromAscii("translate ("); 440cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getX(), true); 441cdf0e10cSrcweir aNewString += aEmptySpace; 442cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate.getY(), true); 443cdf0e10cSrcweir aNewString += aClosingBrace; 444cdf0e10cSrcweir break; 445cdf0e10cSrcweir } 446cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX : 447cdf0e10cSrcweir { 448cdf0e10cSrcweir aNewString += OUString::createFromAscii("skewX ("); 449cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX); 450cdf0e10cSrcweir aNewString += aClosingBrace; 451cdf0e10cSrcweir break; 452cdf0e10cSrcweir } 453cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY : 454cdf0e10cSrcweir { 455cdf0e10cSrcweir aNewString += OUString::createFromAscii("skewY ("); 456cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY); 457cdf0e10cSrcweir aNewString += aClosingBrace; 458cdf0e10cSrcweir break; 459cdf0e10cSrcweir } 460cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX : 461cdf0e10cSrcweir { 462cdf0e10cSrcweir aNewString += OUString::createFromAscii("matrix ("); 463cdf0e10cSrcweir 464cdf0e10cSrcweir // a 465cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 0)); 466cdf0e10cSrcweir aNewString += aEmptySpace; 467cdf0e10cSrcweir 468cdf0e10cSrcweir // b 469cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 0)); 470cdf0e10cSrcweir aNewString += aEmptySpace; 471cdf0e10cSrcweir 472cdf0e10cSrcweir // c 473cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 1)); 474cdf0e10cSrcweir aNewString += aEmptySpace; 475cdf0e10cSrcweir 476cdf0e10cSrcweir // d 477cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 1)); 478cdf0e10cSrcweir aNewString += aEmptySpace; 479cdf0e10cSrcweir 480cdf0e10cSrcweir // e 481cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(0, 2), true); 482cdf0e10cSrcweir aNewString += aEmptySpace; 483cdf0e10cSrcweir 484cdf0e10cSrcweir // f 485cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix.get(1, 2), true); 486cdf0e10cSrcweir 487cdf0e10cSrcweir aNewString += aClosingBrace; 488cdf0e10cSrcweir break; 489cdf0e10cSrcweir } 490cdf0e10cSrcweir default : 491cdf0e10cSrcweir { 492cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform2D: impossible entry!"); 493cdf0e10cSrcweir break; 494cdf0e10cSrcweir } 495cdf0e10cSrcweir } 496cdf0e10cSrcweir 497cdf0e10cSrcweir // if not the last entry, add one space to next tag 498cdf0e10cSrcweir if(a + 1UL != maList.size()) 499cdf0e10cSrcweir { 500cdf0e10cSrcweir aNewString += aEmptySpace; 501cdf0e10cSrcweir } 502cdf0e10cSrcweir } 503cdf0e10cSrcweir 504cdf0e10cSrcweir // fill string form OUString 505cdf0e10cSrcweir msString = aNewString; 506cdf0e10cSrcweir 507cdf0e10cSrcweir return msString; 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 511cdf0e10cSrcweir // for Import: constructor with string, parses it and generates entries 512cdf0e10cSrcweir SdXMLImExTransform2D::SdXMLImExTransform2D(const OUString& rNew, const SvXMLUnitConverter& rConv) 513cdf0e10cSrcweir { 514cdf0e10cSrcweir SetString(rNew, rConv); 515cdf0e10cSrcweir } 516cdf0e10cSrcweir 517cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 518cdf0e10cSrcweir // sets new string, parses it and generates entries 519cdf0e10cSrcweir void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir msString = rNew; 522cdf0e10cSrcweir EmptyList(); 523cdf0e10cSrcweir 524cdf0e10cSrcweir if(msString.getLength()) 525cdf0e10cSrcweir { 526cdf0e10cSrcweir const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); 527cdf0e10cSrcweir const sal_Int32 nLen(aStr.getLength()); 528cdf0e10cSrcweir 529cdf0e10cSrcweir const OUString aString_rotate(OUString::createFromAscii("rotate")); 530cdf0e10cSrcweir const OUString aString_scale(OUString::createFromAscii("scale")); 531cdf0e10cSrcweir const OUString aString_translate(OUString::createFromAscii("translate")); 532cdf0e10cSrcweir const OUString aString_skewX(OUString::createFromAscii("skewX")); 533cdf0e10cSrcweir const OUString aString_skewY(OUString::createFromAscii("skewY")); 534cdf0e10cSrcweir const OUString aString_matrix(OUString::createFromAscii("matrix")); 535cdf0e10cSrcweir 536cdf0e10cSrcweir sal_Int32 nPos(0); 537cdf0e10cSrcweir 538cdf0e10cSrcweir while(nPos < nLen) 539cdf0e10cSrcweir { 540cdf0e10cSrcweir // skip spaces 541cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 542cdf0e10cSrcweir 543cdf0e10cSrcweir // look for tag 544cdf0e10cSrcweir if(nPos < nLen) 545cdf0e10cSrcweir { 546cdf0e10cSrcweir if(nPos == aStr.indexOf(aString_rotate, nPos)) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir double fValue(0.0); 549cdf0e10cSrcweir nPos += 6; 550cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 551cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 552cdf0e10cSrcweir if(fValue != 0.0) 553cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DRotate(fValue)); 554cdf0e10cSrcweir 555cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 556cdf0e10cSrcweir } 557cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_scale, nPos)) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir ::basegfx::B2DTuple aValue(1.0, 1.0); 560cdf0e10cSrcweir nPos += 5; 561cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 562cdf0e10cSrcweir aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX())); 563cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 564cdf0e10cSrcweir aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY())); 565cdf0e10cSrcweir 566cdf0e10cSrcweir if(aValue.getX() != 1.0 || aValue.getY() != 1.0) 567cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DScale(aValue)); 568cdf0e10cSrcweir 569cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 570cdf0e10cSrcweir } 571cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_translate, nPos)) 572cdf0e10cSrcweir { 573cdf0e10cSrcweir ::basegfx::B2DTuple aValue; 574cdf0e10cSrcweir nPos += 9; 575cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 576cdf0e10cSrcweir aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true)); 577cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 578cdf0e10cSrcweir aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true)); 579cdf0e10cSrcweir 580cdf0e10cSrcweir if(!aValue.equalZero()) 581cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DTranslate(aValue)); 582cdf0e10cSrcweir 583cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 584cdf0e10cSrcweir } 585cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_skewX, nPos)) 586cdf0e10cSrcweir { 587cdf0e10cSrcweir double fValue(0.0); 588cdf0e10cSrcweir nPos += 5; 589cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 590cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 591cdf0e10cSrcweir if(fValue != 0.0) 592cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DSkewX(fValue)); 593cdf0e10cSrcweir 594cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 595cdf0e10cSrcweir } 596cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_skewY, nPos)) 597cdf0e10cSrcweir { 598cdf0e10cSrcweir double fValue(0.0); 599cdf0e10cSrcweir nPos += 5; 600cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 601cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 602cdf0e10cSrcweir if(fValue != 0.0) 603cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DSkewY(fValue)); 604cdf0e10cSrcweir 605cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 606cdf0e10cSrcweir } 607cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_matrix, nPos)) 608cdf0e10cSrcweir { 609cdf0e10cSrcweir ::basegfx::B2DHomMatrix aValue; 610cdf0e10cSrcweir 611cdf0e10cSrcweir nPos += 6; 612cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 613cdf0e10cSrcweir 614cdf0e10cSrcweir // a 615cdf0e10cSrcweir aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0))); 616cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 617cdf0e10cSrcweir 618cdf0e10cSrcweir // b 619cdf0e10cSrcweir aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0))); 620cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 621cdf0e10cSrcweir 622cdf0e10cSrcweir // c 623cdf0e10cSrcweir aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1))); 624cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 625cdf0e10cSrcweir 626cdf0e10cSrcweir // d 627cdf0e10cSrcweir aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1))); 628cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 629cdf0e10cSrcweir 630cdf0e10cSrcweir // e 631cdf0e10cSrcweir aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true)); 632cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 633cdf0e10cSrcweir 634cdf0e10cSrcweir // f 635cdf0e10cSrcweir aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true)); 636cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 637cdf0e10cSrcweir 638cdf0e10cSrcweir if(!aValue.isIdentity()) 639cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj2DMatrix(aValue)); 640cdf0e10cSrcweir 641cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 642cdf0e10cSrcweir } 643cdf0e10cSrcweir else 644cdf0e10cSrcweir { 645cdf0e10cSrcweir nPos++; 646cdf0e10cSrcweir } 647cdf0e10cSrcweir } 648cdf0e10cSrcweir } 649cdf0e10cSrcweir } 650cdf0e10cSrcweir } 651cdf0e10cSrcweir 652cdf0e10cSrcweir void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans) 653cdf0e10cSrcweir { 654cdf0e10cSrcweir rFullTrans.identity(); 655cdf0e10cSrcweir 656cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 657cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 658cdf0e10cSrcweir { 659cdf0e10cSrcweir ImpSdXMLExpTransObj2DBase* pObj = maList[a]; 660cdf0e10cSrcweir switch(pObj->mnType) 661cdf0e10cSrcweir { 662cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE : 663cdf0e10cSrcweir { 664cdf0e10cSrcweir // #i78696# 665cdf0e10cSrcweir // mfRotate is mathematically wrong oriented since we export/import the angle 666cdf0e10cSrcweir // values mirrored. This error is fixed in the API, but not yet in the FileFormat. 667cdf0e10cSrcweir // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next 668cdf0e10cSrcweir // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary 669cdf0e10cSrcweir // to mirror the value here 670cdf0e10cSrcweir rFullTrans.rotate(((ImpSdXMLExpTransObj2DRotate*)pObj)->mfRotate * -1.0); 671cdf0e10cSrcweir break; 672cdf0e10cSrcweir } 673cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SCALE : 674cdf0e10cSrcweir { 675cdf0e10cSrcweir const ::basegfx::B2DTuple& rScale = ((ImpSdXMLExpTransObj2DScale*)pObj)->maScale; 676cdf0e10cSrcweir rFullTrans.scale(rScale.getX(), rScale.getY()); 677cdf0e10cSrcweir break; 678cdf0e10cSrcweir } 679cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE : 680cdf0e10cSrcweir { 681cdf0e10cSrcweir const ::basegfx::B2DTuple& rTranslate = ((ImpSdXMLExpTransObj2DTranslate*)pObj)->maTranslate; 682cdf0e10cSrcweir rFullTrans.translate(rTranslate.getX(), rTranslate.getY()); 683cdf0e10cSrcweir break; 684cdf0e10cSrcweir } 685cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX : 686cdf0e10cSrcweir { 687cdf0e10cSrcweir rFullTrans.shearX(tan(((ImpSdXMLExpTransObj2DSkewX*)pObj)->mfSkewX)); 688cdf0e10cSrcweir break; 689cdf0e10cSrcweir } 690cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY : 691cdf0e10cSrcweir { 692cdf0e10cSrcweir rFullTrans.shearY(tan(((ImpSdXMLExpTransObj2DSkewY*)pObj)->mfSkewY)); 693cdf0e10cSrcweir break; 694cdf0e10cSrcweir } 695cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX : 696cdf0e10cSrcweir { 697cdf0e10cSrcweir rFullTrans *= ((ImpSdXMLExpTransObj2DMatrix*)pObj)->maMatrix; 698cdf0e10cSrcweir break; 699cdf0e10cSrcweir } 700cdf0e10cSrcweir default : 701cdf0e10cSrcweir { 702cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform2D: impossible entry!"); 703cdf0e10cSrcweir break; 704cdf0e10cSrcweir } 705cdf0e10cSrcweir } 706cdf0e10cSrcweir } 707cdf0e10cSrcweir } 708cdf0e10cSrcweir 709cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 710cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 711cdf0e10cSrcweir // base class of all 3D transform objects 712cdf0e10cSrcweir 713cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DBase 714cdf0e10cSrcweir { 715cdf0e10cSrcweir sal_uInt16 mnType; 716cdf0e10cSrcweir ImpSdXMLExpTransObj3DBase(sal_uInt16 nType) 717cdf0e10cSrcweir : mnType(nType) {} 718cdf0e10cSrcweir }; 719cdf0e10cSrcweir 720cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 721cdf0e10cSrcweir // possible object types for 3D 722cdf0e10cSrcweir 723cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X 0x0000 724cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y 0x0001 725cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z 0x0002 726cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_SCALE 0x0003 727cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE 0x0004 728cdf0e10cSrcweir #define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX 0x0005 729cdf0e10cSrcweir 730cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 731cdf0e10cSrcweir // classes of objects, different sizes 732cdf0e10cSrcweir 733cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase 734cdf0e10cSrcweir { 735cdf0e10cSrcweir double mfRotateX; 736cdf0e10cSrcweir ImpSdXMLExpTransObj3DRotateX(double fVal) 737cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X), mfRotateX(fVal) {} 738cdf0e10cSrcweir }; 739cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase 740cdf0e10cSrcweir { 741cdf0e10cSrcweir double mfRotateY; 742cdf0e10cSrcweir ImpSdXMLExpTransObj3DRotateY(double fVal) 743cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y), mfRotateY(fVal) {} 744cdf0e10cSrcweir }; 745cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase 746cdf0e10cSrcweir { 747cdf0e10cSrcweir double mfRotateZ; 748cdf0e10cSrcweir ImpSdXMLExpTransObj3DRotateZ(double fVal) 749cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z), mfRotateZ(fVal) {} 750cdf0e10cSrcweir }; 751cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase 752cdf0e10cSrcweir { 753cdf0e10cSrcweir ::basegfx::B3DTuple maScale; 754cdf0e10cSrcweir ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew) 755cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE), maScale(rNew) {} 756cdf0e10cSrcweir }; 757cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase 758cdf0e10cSrcweir { 759cdf0e10cSrcweir ::basegfx::B3DTuple maTranslate; 760cdf0e10cSrcweir ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew) 761cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE), maTranslate(rNew) {} 762cdf0e10cSrcweir }; 763cdf0e10cSrcweir struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase 764cdf0e10cSrcweir { 765cdf0e10cSrcweir ::basegfx::B3DHomMatrix maMatrix; 766cdf0e10cSrcweir ImpSdXMLExpTransObj3DMatrix(const ::basegfx::B3DHomMatrix& rNew) 767cdf0e10cSrcweir : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX), maMatrix(rNew) {} 768cdf0e10cSrcweir }; 769cdf0e10cSrcweir 770cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 771cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 772cdf0e10cSrcweir // delete all entries in list 773cdf0e10cSrcweir 774cdf0e10cSrcweir void SdXMLImExTransform3D::EmptyList() 775cdf0e10cSrcweir { 776cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 777cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 778cdf0e10cSrcweir { 779cdf0e10cSrcweir ImpSdXMLExpTransObj3DBase* pObj = maList[a]; 780cdf0e10cSrcweir 781cdf0e10cSrcweir switch(pObj->mnType) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X : 784cdf0e10cSrcweir { 785cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DRotateX*)pObj; 786cdf0e10cSrcweir break; 787cdf0e10cSrcweir } 788cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y : 789cdf0e10cSrcweir { 790cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DRotateY*)pObj; 791cdf0e10cSrcweir break; 792cdf0e10cSrcweir } 793cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z : 794cdf0e10cSrcweir { 795cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DRotateZ*)pObj; 796cdf0e10cSrcweir break; 797cdf0e10cSrcweir } 798cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_SCALE : 799cdf0e10cSrcweir { 800cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DScale*)pObj; 801cdf0e10cSrcweir break; 802cdf0e10cSrcweir } 803cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE : 804cdf0e10cSrcweir { 805cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DTranslate*)pObj; 806cdf0e10cSrcweir break; 807cdf0e10cSrcweir } 808cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX : 809cdf0e10cSrcweir { 810cdf0e10cSrcweir delete (ImpSdXMLExpTransObj3DMatrix*)pObj; 811cdf0e10cSrcweir break; 812cdf0e10cSrcweir } 813cdf0e10cSrcweir default : 814cdf0e10cSrcweir { 815cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform3D: impossible entry!"); 816cdf0e10cSrcweir break; 817cdf0e10cSrcweir } 818cdf0e10cSrcweir } 819cdf0e10cSrcweir } 820cdf0e10cSrcweir 821cdf0e10cSrcweir maList.clear(); 822cdf0e10cSrcweir } 823cdf0e10cSrcweir 824cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 825cdf0e10cSrcweir // add members 826cdf0e10cSrcweir 827cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateX(double fNew) 828cdf0e10cSrcweir { 829cdf0e10cSrcweir if(fNew != 0.0) 830cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateX(fNew)); 831cdf0e10cSrcweir } 832cdf0e10cSrcweir 833cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateY(double fNew) 834cdf0e10cSrcweir { 835cdf0e10cSrcweir if(fNew != 0.0) 836cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateY(fNew)); 837cdf0e10cSrcweir } 838cdf0e10cSrcweir 839cdf0e10cSrcweir void SdXMLImExTransform3D::AddRotateZ(double fNew) 840cdf0e10cSrcweir { 841cdf0e10cSrcweir if(fNew != 0.0) 842cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(fNew)); 843cdf0e10cSrcweir } 844cdf0e10cSrcweir 845cdf0e10cSrcweir void SdXMLImExTransform3D::AddScale(const ::basegfx::B3DTuple& rNew) 846cdf0e10cSrcweir { 847cdf0e10cSrcweir if(1.0 != rNew.getX() || 1.0 != rNew.getY() || 1.0 != rNew.getZ()) 848cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DScale(rNew)); 849cdf0e10cSrcweir } 850cdf0e10cSrcweir 851cdf0e10cSrcweir void SdXMLImExTransform3D::AddTranslate(const ::basegfx::B3DTuple& rNew) 852cdf0e10cSrcweir { 853cdf0e10cSrcweir if(!rNew.equalZero()) 854cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DTranslate(rNew)); 855cdf0e10cSrcweir } 856cdf0e10cSrcweir 857cdf0e10cSrcweir void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew) 858cdf0e10cSrcweir { 859cdf0e10cSrcweir if(!rNew.isIdentity()) 860cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DMatrix(rNew)); 861cdf0e10cSrcweir } 862cdf0e10cSrcweir 863cdf0e10cSrcweir void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat) 864cdf0e10cSrcweir { 865cdf0e10cSrcweir ::basegfx::B3DHomMatrix aExportMatrix; 866cdf0e10cSrcweir 867cdf0e10cSrcweir aExportMatrix.set(0, 0, xHomMat.Line1.Column1); 868cdf0e10cSrcweir aExportMatrix.set(0, 1, xHomMat.Line1.Column2); 869cdf0e10cSrcweir aExportMatrix.set(0, 2, xHomMat.Line1.Column3); 870cdf0e10cSrcweir aExportMatrix.set(0, 3, xHomMat.Line1.Column4); 871cdf0e10cSrcweir aExportMatrix.set(1, 0, xHomMat.Line2.Column1); 872cdf0e10cSrcweir aExportMatrix.set(1, 1, xHomMat.Line2.Column2); 873cdf0e10cSrcweir aExportMatrix.set(1, 2, xHomMat.Line2.Column3); 874cdf0e10cSrcweir aExportMatrix.set(1, 3, xHomMat.Line2.Column4); 875cdf0e10cSrcweir aExportMatrix.set(2, 0, xHomMat.Line3.Column1); 876cdf0e10cSrcweir aExportMatrix.set(2, 1, xHomMat.Line3.Column2); 877cdf0e10cSrcweir aExportMatrix.set(2, 2, xHomMat.Line3.Column3); 878cdf0e10cSrcweir aExportMatrix.set(2, 3, xHomMat.Line3.Column4); 879cdf0e10cSrcweir 880cdf0e10cSrcweir AddMatrix(aExportMatrix); 881cdf0e10cSrcweir } 882cdf0e10cSrcweir 883cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 884cdf0e10cSrcweir // gen string for export 885cdf0e10cSrcweir const OUString& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter& rConv) 886cdf0e10cSrcweir { 887cdf0e10cSrcweir OUString aNewString; 888cdf0e10cSrcweir OUString aClosingBrace(sal_Unicode(')')); 889cdf0e10cSrcweir OUString aEmptySpace(sal_Unicode(' ')); 890cdf0e10cSrcweir 891cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 892cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 893cdf0e10cSrcweir { 894cdf0e10cSrcweir ImpSdXMLExpTransObj3DBase* pObj = maList[a]; 895cdf0e10cSrcweir switch(pObj->mnType) 896cdf0e10cSrcweir { 897cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X : 898cdf0e10cSrcweir { 899cdf0e10cSrcweir aNewString += OUString::createFromAscii("rotatex ("); 900cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX); 901cdf0e10cSrcweir aNewString += aClosingBrace; 902cdf0e10cSrcweir break; 903cdf0e10cSrcweir } 904cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y : 905cdf0e10cSrcweir { 906cdf0e10cSrcweir aNewString += OUString::createFromAscii("rotatey ("); 907cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY); 908cdf0e10cSrcweir aNewString += aClosingBrace; 909cdf0e10cSrcweir break; 910cdf0e10cSrcweir } 911cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z : 912cdf0e10cSrcweir { 913cdf0e10cSrcweir aNewString += OUString::createFromAscii("rotatez ("); 914cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ); 915cdf0e10cSrcweir aNewString += aClosingBrace; 916cdf0e10cSrcweir break; 917cdf0e10cSrcweir } 918cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_SCALE : 919cdf0e10cSrcweir { 920cdf0e10cSrcweir aNewString += OUString::createFromAscii("scale ("); 921cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getX()); 922cdf0e10cSrcweir aNewString += aEmptySpace; 923cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getY()); 924cdf0e10cSrcweir aNewString += aEmptySpace; 925cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale.getZ()); 926cdf0e10cSrcweir aNewString += aClosingBrace; 927cdf0e10cSrcweir break; 928cdf0e10cSrcweir } 929cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE : 930cdf0e10cSrcweir { 931cdf0e10cSrcweir aNewString += OUString::createFromAscii("translate ("); 932cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getX(), true); 933cdf0e10cSrcweir aNewString += aEmptySpace; 934cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getY(), true); 935cdf0e10cSrcweir aNewString += aEmptySpace; 936cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate.getZ(), true); 937cdf0e10cSrcweir aNewString += aClosingBrace; 938cdf0e10cSrcweir break; 939cdf0e10cSrcweir } 940cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX : 941cdf0e10cSrcweir { 942cdf0e10cSrcweir aNewString += OUString::createFromAscii("matrix ("); 943cdf0e10cSrcweir 944cdf0e10cSrcweir // a 945cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 0)); 946cdf0e10cSrcweir aNewString += aEmptySpace; 947cdf0e10cSrcweir 948cdf0e10cSrcweir // b 949cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 0)); 950cdf0e10cSrcweir aNewString += aEmptySpace; 951cdf0e10cSrcweir 952cdf0e10cSrcweir // c 953cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 0)); 954cdf0e10cSrcweir aNewString += aEmptySpace; 955cdf0e10cSrcweir 956cdf0e10cSrcweir // d 957cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 1)); 958cdf0e10cSrcweir aNewString += aEmptySpace; 959cdf0e10cSrcweir 960cdf0e10cSrcweir // e 961cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 1)); 962cdf0e10cSrcweir aNewString += aEmptySpace; 963cdf0e10cSrcweir 964cdf0e10cSrcweir // f 965cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 1)); 966cdf0e10cSrcweir aNewString += aEmptySpace; 967cdf0e10cSrcweir 968cdf0e10cSrcweir // g 969cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 2)); 970cdf0e10cSrcweir aNewString += aEmptySpace; 971cdf0e10cSrcweir 972cdf0e10cSrcweir // h 973cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 2)); 974cdf0e10cSrcweir aNewString += aEmptySpace; 975cdf0e10cSrcweir 976cdf0e10cSrcweir // i 977cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 2)); 978cdf0e10cSrcweir aNewString += aEmptySpace; 979cdf0e10cSrcweir 980cdf0e10cSrcweir // j 981cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(0, 3), true); 982cdf0e10cSrcweir aNewString += aEmptySpace; 983cdf0e10cSrcweir 984cdf0e10cSrcweir // k 985cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(1, 3), true); 986cdf0e10cSrcweir aNewString += aEmptySpace; 987cdf0e10cSrcweir 988cdf0e10cSrcweir // l 989cdf0e10cSrcweir Imp_PutDoubleChar(aNewString, rConv, ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix.get(2, 3), true); 990cdf0e10cSrcweir 991cdf0e10cSrcweir aNewString += aClosingBrace; 992cdf0e10cSrcweir break; 993cdf0e10cSrcweir } 994cdf0e10cSrcweir default : 995cdf0e10cSrcweir { 996cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform3D: impossible entry!"); 997cdf0e10cSrcweir break; 998cdf0e10cSrcweir } 999cdf0e10cSrcweir } 1000cdf0e10cSrcweir 1001cdf0e10cSrcweir // if not the last entry, add one space to next tag 1002cdf0e10cSrcweir if(a + 1UL != maList.size()) 1003cdf0e10cSrcweir { 1004cdf0e10cSrcweir aNewString += aEmptySpace; 1005cdf0e10cSrcweir } 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir 1008cdf0e10cSrcweir // fill string form OUString 1009cdf0e10cSrcweir msString = aNewString; 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir return msString; 1012cdf0e10cSrcweir } 1013cdf0e10cSrcweir 1014cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1015cdf0e10cSrcweir // for Import: constructor with string, parses it and generates entries 1016cdf0e10cSrcweir SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString& rNew, const SvXMLUnitConverter& rConv) 1017cdf0e10cSrcweir { 1018cdf0e10cSrcweir SetString(rNew, rConv); 1019cdf0e10cSrcweir } 1020cdf0e10cSrcweir 1021cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1022cdf0e10cSrcweir // sets new string, parses it and generates entries 1023cdf0e10cSrcweir void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv) 1024cdf0e10cSrcweir { 1025cdf0e10cSrcweir msString = rNew; 1026cdf0e10cSrcweir EmptyList(); 1027cdf0e10cSrcweir 1028cdf0e10cSrcweir if(msString.getLength()) 1029cdf0e10cSrcweir { 1030cdf0e10cSrcweir const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); 1031cdf0e10cSrcweir const sal_Int32 nLen(aStr.getLength()); 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir const OUString aString_rotatex(OUString::createFromAscii("rotatex")); 1034cdf0e10cSrcweir const OUString aString_rotatey(OUString::createFromAscii("rotatey")); 1035cdf0e10cSrcweir const OUString aString_rotatez(OUString::createFromAscii("rotatez")); 1036cdf0e10cSrcweir const OUString aString_scale(OUString::createFromAscii("scale")); 1037cdf0e10cSrcweir const OUString aString_translate(OUString::createFromAscii("translate")); 1038cdf0e10cSrcweir const OUString aString_matrix(OUString::createFromAscii("matrix")); 1039cdf0e10cSrcweir 1040cdf0e10cSrcweir sal_Int32 nPos(0); 1041cdf0e10cSrcweir 1042cdf0e10cSrcweir while(nPos < nLen) 1043cdf0e10cSrcweir { 1044cdf0e10cSrcweir // skip spaces 1045cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 1046cdf0e10cSrcweir 1047cdf0e10cSrcweir // look for tag 1048cdf0e10cSrcweir if(nPos < nLen) 1049cdf0e10cSrcweir { 1050cdf0e10cSrcweir if(nPos == aStr.indexOf(aString_rotatex, nPos)) 1051cdf0e10cSrcweir { 1052cdf0e10cSrcweir double fValue(0.0); 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir nPos += 7; 1055cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1056cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 1057cdf0e10cSrcweir if(fValue != 0.0) 1058cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateX(fValue)); 1059cdf0e10cSrcweir 1060cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1061cdf0e10cSrcweir } 1062cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_rotatey, nPos)) 1063cdf0e10cSrcweir { 1064cdf0e10cSrcweir double fValue(0.0); 1065cdf0e10cSrcweir 1066cdf0e10cSrcweir nPos += 7; 1067cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1068cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 1069cdf0e10cSrcweir if(fValue != 0.0) 1070cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateY(fValue)); 1071cdf0e10cSrcweir 1072cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1073cdf0e10cSrcweir } 1074cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_rotatez, nPos)) 1075cdf0e10cSrcweir { 1076cdf0e10cSrcweir double fValue(0.0); 1077cdf0e10cSrcweir 1078cdf0e10cSrcweir nPos += 7; 1079cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1080cdf0e10cSrcweir fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue); 1081cdf0e10cSrcweir if(fValue != 0.0) 1082cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DRotateZ(fValue)); 1083cdf0e10cSrcweir 1084cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1085cdf0e10cSrcweir } 1086cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_scale, nPos)) 1087cdf0e10cSrcweir { 1088cdf0e10cSrcweir ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0); 1089cdf0e10cSrcweir 1090cdf0e10cSrcweir nPos += 5; 1091cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1092cdf0e10cSrcweir aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX())); 1093cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1094cdf0e10cSrcweir aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY())); 1095cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1096cdf0e10cSrcweir aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ())); 1097cdf0e10cSrcweir 1098cdf0e10cSrcweir if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ()) 1099cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DScale(aValue)); 1100cdf0e10cSrcweir 1101cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1102cdf0e10cSrcweir } 1103cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_translate, nPos)) 1104cdf0e10cSrcweir { 1105cdf0e10cSrcweir ::basegfx::B3DTuple aValue; 1106cdf0e10cSrcweir 1107cdf0e10cSrcweir nPos += 9; 1108cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1109cdf0e10cSrcweir aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true)); 1110cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1111cdf0e10cSrcweir aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true)); 1112cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1113cdf0e10cSrcweir aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true)); 1114cdf0e10cSrcweir 1115cdf0e10cSrcweir if(!aValue.equalZero()) 1116cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DTranslate(aValue)); 1117cdf0e10cSrcweir 1118cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1119cdf0e10cSrcweir } 1120cdf0e10cSrcweir else if(nPos == aStr.indexOf(aString_matrix, nPos)) 1121cdf0e10cSrcweir { 1122cdf0e10cSrcweir ::basegfx::B3DHomMatrix aValue; 1123cdf0e10cSrcweir 1124cdf0e10cSrcweir nPos += 6; 1125cdf0e10cSrcweir Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen); 1126cdf0e10cSrcweir 1127cdf0e10cSrcweir // a 1128cdf0e10cSrcweir aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0))); 1129cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1130cdf0e10cSrcweir 1131cdf0e10cSrcweir // b 1132cdf0e10cSrcweir aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0))); 1133cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir // c 1136cdf0e10cSrcweir aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0))); 1137cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1138cdf0e10cSrcweir 1139cdf0e10cSrcweir // d 1140cdf0e10cSrcweir aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1))); 1141cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1142cdf0e10cSrcweir 1143cdf0e10cSrcweir // e 1144cdf0e10cSrcweir aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1))); 1145cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1146cdf0e10cSrcweir 1147cdf0e10cSrcweir // f 1148cdf0e10cSrcweir aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1))); 1149cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1150cdf0e10cSrcweir 1151cdf0e10cSrcweir // g 1152cdf0e10cSrcweir aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2))); 1153cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1154cdf0e10cSrcweir 1155cdf0e10cSrcweir // h 1156cdf0e10cSrcweir aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2))); 1157cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1158cdf0e10cSrcweir 1159cdf0e10cSrcweir // i 1160cdf0e10cSrcweir aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2))); 1161cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir // j 1164cdf0e10cSrcweir aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true)); 1165cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1166cdf0e10cSrcweir 1167cdf0e10cSrcweir // k 1168cdf0e10cSrcweir aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true)); 1169cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1170cdf0e10cSrcweir 1171cdf0e10cSrcweir // l 1172cdf0e10cSrcweir aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true)); 1173cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1174cdf0e10cSrcweir 1175cdf0e10cSrcweir if(!aValue.isIdentity()) 1176cdf0e10cSrcweir maList.push_back(new ImpSdXMLExpTransObj3DMatrix(aValue)); 1177cdf0e10cSrcweir 1178cdf0e10cSrcweir Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen); 1179cdf0e10cSrcweir } 1180cdf0e10cSrcweir else 1181cdf0e10cSrcweir { 1182cdf0e10cSrcweir nPos++; 1183cdf0e10cSrcweir } 1184cdf0e10cSrcweir } 1185cdf0e10cSrcweir } 1186cdf0e10cSrcweir } 1187cdf0e10cSrcweir } 1188cdf0e10cSrcweir 1189cdf0e10cSrcweir bool SdXMLImExTransform3D::GetFullHomogenTransform(com::sun::star::drawing::HomogenMatrix& xHomMat) 1190cdf0e10cSrcweir { 1191cdf0e10cSrcweir ::basegfx::B3DHomMatrix aFullTransform; 1192cdf0e10cSrcweir GetFullTransform(aFullTransform); 1193cdf0e10cSrcweir 1194cdf0e10cSrcweir if(!aFullTransform.isIdentity()) 1195cdf0e10cSrcweir { 1196cdf0e10cSrcweir xHomMat.Line1.Column1 = aFullTransform.get(0, 0); 1197cdf0e10cSrcweir xHomMat.Line1.Column2 = aFullTransform.get(0, 1); 1198cdf0e10cSrcweir xHomMat.Line1.Column3 = aFullTransform.get(0, 2); 1199cdf0e10cSrcweir xHomMat.Line1.Column4 = aFullTransform.get(0, 3); 1200cdf0e10cSrcweir 1201cdf0e10cSrcweir xHomMat.Line2.Column1 = aFullTransform.get(1, 0); 1202cdf0e10cSrcweir xHomMat.Line2.Column2 = aFullTransform.get(1, 1); 1203cdf0e10cSrcweir xHomMat.Line2.Column3 = aFullTransform.get(1, 2); 1204cdf0e10cSrcweir xHomMat.Line2.Column4 = aFullTransform.get(1, 3); 1205cdf0e10cSrcweir 1206cdf0e10cSrcweir xHomMat.Line3.Column1 = aFullTransform.get(2, 0); 1207cdf0e10cSrcweir xHomMat.Line3.Column2 = aFullTransform.get(2, 1); 1208cdf0e10cSrcweir xHomMat.Line3.Column3 = aFullTransform.get(2, 2); 1209cdf0e10cSrcweir xHomMat.Line3.Column4 = aFullTransform.get(2, 3); 1210cdf0e10cSrcweir 1211cdf0e10cSrcweir xHomMat.Line4.Column1 = aFullTransform.get(3, 0); 1212cdf0e10cSrcweir xHomMat.Line4.Column2 = aFullTransform.get(3, 1); 1213cdf0e10cSrcweir xHomMat.Line4.Column3 = aFullTransform.get(3, 2); 1214cdf0e10cSrcweir xHomMat.Line4.Column4 = aFullTransform.get(3, 3); 1215cdf0e10cSrcweir 1216cdf0e10cSrcweir return true; 1217cdf0e10cSrcweir } 1218cdf0e10cSrcweir 1219cdf0e10cSrcweir return false; 1220cdf0e10cSrcweir } 1221cdf0e10cSrcweir 1222cdf0e10cSrcweir void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans) 1223cdf0e10cSrcweir { 1224cdf0e10cSrcweir rFullTrans.identity(); 1225cdf0e10cSrcweir 1226cdf0e10cSrcweir const sal_uInt32 nCount = maList.size(); 1227cdf0e10cSrcweir for(sal_uInt32 a(0L); a < nCount; a++) 1228cdf0e10cSrcweir { 1229cdf0e10cSrcweir ImpSdXMLExpTransObj3DBase* pObj = maList[a]; 1230cdf0e10cSrcweir switch(pObj->mnType) 1231cdf0e10cSrcweir { 1232cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X : 1233cdf0e10cSrcweir { 1234cdf0e10cSrcweir rFullTrans.rotate(((ImpSdXMLExpTransObj3DRotateX*)pObj)->mfRotateX, 0.0, 0.0); 1235cdf0e10cSrcweir break; 1236cdf0e10cSrcweir } 1237cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y : 1238cdf0e10cSrcweir { 1239cdf0e10cSrcweir rFullTrans.rotate(0.0, ((ImpSdXMLExpTransObj3DRotateY*)pObj)->mfRotateY, 0.0); 1240cdf0e10cSrcweir break; 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z : 1243cdf0e10cSrcweir { 1244cdf0e10cSrcweir rFullTrans.rotate(0.0, 0.0, ((ImpSdXMLExpTransObj3DRotateZ*)pObj)->mfRotateZ); 1245cdf0e10cSrcweir break; 1246cdf0e10cSrcweir } 1247cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_SCALE : 1248cdf0e10cSrcweir { 1249cdf0e10cSrcweir const ::basegfx::B3DTuple& rScale = ((ImpSdXMLExpTransObj3DScale*)pObj)->maScale; 1250cdf0e10cSrcweir rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ()); 1251cdf0e10cSrcweir break; 1252cdf0e10cSrcweir } 1253cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE : 1254cdf0e10cSrcweir { 1255cdf0e10cSrcweir const ::basegfx::B3DTuple& rTranslate = ((ImpSdXMLExpTransObj3DTranslate*)pObj)->maTranslate; 1256cdf0e10cSrcweir rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ()); 1257cdf0e10cSrcweir break; 1258cdf0e10cSrcweir } 1259cdf0e10cSrcweir case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX : 1260cdf0e10cSrcweir { 1261cdf0e10cSrcweir rFullTrans *= ((ImpSdXMLExpTransObj3DMatrix*)pObj)->maMatrix; 1262cdf0e10cSrcweir break; 1263cdf0e10cSrcweir } 1264cdf0e10cSrcweir default : 1265cdf0e10cSrcweir { 1266cdf0e10cSrcweir DBG_ERROR("SdXMLImExTransform3D: impossible entry!"); 1267cdf0e10cSrcweir break; 1268cdf0e10cSrcweir } 1269cdf0e10cSrcweir } 1270cdf0e10cSrcweir } 1271cdf0e10cSrcweir } 1272cdf0e10cSrcweir 1273cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1274cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1275cdf0e10cSrcweir 1276cdf0e10cSrcweir SdXMLImExViewBox::SdXMLImExViewBox(sal_Int32 nX, sal_Int32 nY, sal_Int32 nW, sal_Int32 nH) 1277cdf0e10cSrcweir : mnX( nX ), 1278cdf0e10cSrcweir mnY( nY ), 1279cdf0e10cSrcweir mnW( nW ), 1280cdf0e10cSrcweir mnH( nH ) 1281cdf0e10cSrcweir { 1282cdf0e10cSrcweir } 1283cdf0e10cSrcweir 1284cdf0e10cSrcweir // #100617# Asked vincent hardy: svg:viewBox values may be double precision. 1285cdf0e10cSrcweir SdXMLImExViewBox::SdXMLImExViewBox(const OUString& rNew, const SvXMLUnitConverter& rConv) 1286cdf0e10cSrcweir : msString(rNew), 1287cdf0e10cSrcweir mnX( 0L ), 1288cdf0e10cSrcweir mnY( 0L ), 1289cdf0e10cSrcweir mnW( 1000L ), 1290cdf0e10cSrcweir mnH( 1000L ) 1291cdf0e10cSrcweir { 1292cdf0e10cSrcweir if(msString.getLength()) 1293cdf0e10cSrcweir { 1294cdf0e10cSrcweir const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); 1295cdf0e10cSrcweir const sal_Int32 nLen(aStr.getLength()); 1296cdf0e10cSrcweir sal_Int32 nPos(0); 1297cdf0e10cSrcweir 1298cdf0e10cSrcweir // skip starting spaces 1299cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 1300cdf0e10cSrcweir 1301cdf0e10cSrcweir // get mX, #100617# be prepared for doubles 1302cdf0e10cSrcweir mnX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnX)); 1303cdf0e10cSrcweir 1304cdf0e10cSrcweir // skip spaces and commas 1305cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1306cdf0e10cSrcweir 1307cdf0e10cSrcweir // get mY, #100617# be prepared for doubles 1308cdf0e10cSrcweir mnY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnY)); 1309cdf0e10cSrcweir 1310cdf0e10cSrcweir // skip spaces and commas 1311cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1312cdf0e10cSrcweir 1313cdf0e10cSrcweir // get mW, #100617# be prepared for doubles 1314cdf0e10cSrcweir mnW = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnW)); 1315cdf0e10cSrcweir 1316cdf0e10cSrcweir // skip spaces and commas 1317cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1318cdf0e10cSrcweir 1319cdf0e10cSrcweir // get mH, #100617# be prepared for doubles 1320cdf0e10cSrcweir mnH = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)mnH)); 1321cdf0e10cSrcweir } 1322cdf0e10cSrcweir } 1323cdf0e10cSrcweir 1324cdf0e10cSrcweir const OUString& SdXMLImExViewBox::GetExportString() 1325cdf0e10cSrcweir { 1326cdf0e10cSrcweir OUString aNewString; 1327cdf0e10cSrcweir OUString aEmptySpace(sal_Unicode(' ')); 1328cdf0e10cSrcweir 1329cdf0e10cSrcweir Imp_PutNumberChar(aNewString, mnX); 1330cdf0e10cSrcweir aNewString += aEmptySpace; 1331cdf0e10cSrcweir 1332cdf0e10cSrcweir Imp_PutNumberChar(aNewString, mnY); 1333cdf0e10cSrcweir aNewString += aEmptySpace; 1334cdf0e10cSrcweir 1335cdf0e10cSrcweir Imp_PutNumberChar(aNewString, mnW); 1336cdf0e10cSrcweir aNewString += aEmptySpace; 1337cdf0e10cSrcweir 1338cdf0e10cSrcweir Imp_PutNumberChar(aNewString, mnH); 1339cdf0e10cSrcweir 1340cdf0e10cSrcweir // set new string 1341cdf0e10cSrcweir msString = aNewString; 1342cdf0e10cSrcweir 1343cdf0e10cSrcweir return msString; 1344cdf0e10cSrcweir } 1345cdf0e10cSrcweir 1346cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1347cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1348cdf0e10cSrcweir 1349cdf0e10cSrcweir SdXMLImExPointsElement::SdXMLImExPointsElement(drawing::PointSequence* pPoints, 1350cdf0e10cSrcweir const SdXMLImExViewBox& rViewBox, 1351cdf0e10cSrcweir const awt::Point& rObjectPos, 1352cdf0e10cSrcweir const awt::Size& rObjectSize, 1353cdf0e10cSrcweir // #96328# 1354cdf0e10cSrcweir const bool bClosed) 1355cdf0e10cSrcweir : maPoly( 0L ) 1356cdf0e10cSrcweir { 1357cdf0e10cSrcweir DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExPointsElement(!)"); 1358cdf0e10cSrcweir 1359cdf0e10cSrcweir // add polygon to string 1360cdf0e10cSrcweir sal_Int32 nCnt(pPoints->getLength()); 1361cdf0e10cSrcweir 1362cdf0e10cSrcweir // #104076# Convert to string only when at last one point included 1363cdf0e10cSrcweir if(nCnt > 0) 1364cdf0e10cSrcweir { 1365cdf0e10cSrcweir OUString aNewString; 1366cdf0e10cSrcweir awt::Point* pArray = pPoints->getArray(); 1367cdf0e10cSrcweir 1368cdf0e10cSrcweir // last point same? Ignore it. 1369cdf0e10cSrcweir // #96328# ...but only when polygon is CLOSED 1370cdf0e10cSrcweir if(bClosed && (pArray->X == (pArray + (nCnt - 1))->X) && (pArray->Y == (pArray + (nCnt - 1))->Y)) 1371cdf0e10cSrcweir nCnt--; 1372cdf0e10cSrcweir 1373cdf0e10cSrcweir // object size and ViewBox size different? 1374cdf0e10cSrcweir bool bScale(rObjectSize.Width != rViewBox.GetWidth() 1375cdf0e10cSrcweir || rObjectSize.Height != rViewBox.GetHeight()); 1376cdf0e10cSrcweir bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); 1377cdf0e10cSrcweir 1378cdf0e10cSrcweir for(sal_Int32 a(0L); a < nCnt; a++) 1379cdf0e10cSrcweir { 1380cdf0e10cSrcweir // prepare coordinates 1381cdf0e10cSrcweir sal_Int32 nX( pArray->X - rObjectPos.X ); 1382cdf0e10cSrcweir sal_Int32 nY( pArray->Y - rObjectPos.Y ); 1383cdf0e10cSrcweir 1384cdf0e10cSrcweir if(bScale && rObjectSize.Width && rObjectSize.Height) 1385cdf0e10cSrcweir { 1386cdf0e10cSrcweir nX = (nX * rViewBox.GetWidth()) / rObjectSize.Width; 1387cdf0e10cSrcweir nY = (nY * rViewBox.GetHeight()) / rObjectSize.Height; 1388cdf0e10cSrcweir } 1389cdf0e10cSrcweir 1390cdf0e10cSrcweir if(bTranslate) 1391cdf0e10cSrcweir { 1392cdf0e10cSrcweir nX += rViewBox.GetX(); 1393cdf0e10cSrcweir nY += rViewBox.GetY(); 1394cdf0e10cSrcweir } 1395cdf0e10cSrcweir 1396cdf0e10cSrcweir // X and comma 1397cdf0e10cSrcweir Imp_PutNumberChar(aNewString, nX); 1398cdf0e10cSrcweir aNewString += String(sal_Unicode(',')); 1399cdf0e10cSrcweir 1400cdf0e10cSrcweir // Y and space (not for last) 1401cdf0e10cSrcweir Imp_PutNumberChar(aNewString, nY); 1402cdf0e10cSrcweir if(a + 1 != nCnt) 1403cdf0e10cSrcweir aNewString += String(sal_Unicode(' ')); 1404cdf0e10cSrcweir 1405cdf0e10cSrcweir // next point 1406cdf0e10cSrcweir pArray++; 1407cdf0e10cSrcweir } 1408cdf0e10cSrcweir 1409cdf0e10cSrcweir // set new string 1410cdf0e10cSrcweir msString = aNewString; 1411cdf0e10cSrcweir } 1412cdf0e10cSrcweir } 1413cdf0e10cSrcweir 1414cdf0e10cSrcweir // #100617# svg:polyline or svg:polygon values may be double precision. 1415cdf0e10cSrcweir SdXMLImExPointsElement::SdXMLImExPointsElement(const OUString& rNew, 1416cdf0e10cSrcweir const SdXMLImExViewBox& rViewBox, 1417cdf0e10cSrcweir const awt::Point& rObjectPos, 1418cdf0e10cSrcweir const awt::Size& rObjectSize, 1419cdf0e10cSrcweir const SvXMLUnitConverter& rConv) 1420cdf0e10cSrcweir : msString( rNew ), 1421cdf0e10cSrcweir maPoly( 0L ) 1422cdf0e10cSrcweir { 1423cdf0e10cSrcweir // convert string to polygon 1424cdf0e10cSrcweir const OUString aStr(msString.getStr(), (sal_uInt16)msString.getLength()); 1425cdf0e10cSrcweir const sal_Int32 nLen(aStr.getLength()); 1426cdf0e10cSrcweir sal_Int32 nPos(0); 1427cdf0e10cSrcweir sal_Int32 nNumPoints(0L); 1428cdf0e10cSrcweir 1429cdf0e10cSrcweir // skip starting spaces 1430cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 1431cdf0e10cSrcweir 1432cdf0e10cSrcweir // count points in first loop 1433cdf0e10cSrcweir while(nPos < nLen) 1434cdf0e10cSrcweir { 1435cdf0e10cSrcweir // skip number, #100617# be prepared for doubles 1436cdf0e10cSrcweir Imp_SkipDouble(aStr, nPos, nLen); 1437cdf0e10cSrcweir 1438cdf0e10cSrcweir // skip spaces and commas 1439cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1440cdf0e10cSrcweir 1441cdf0e10cSrcweir // skip number, #100617# be prepared for doubles 1442cdf0e10cSrcweir Imp_SkipDouble(aStr, nPos, nLen); 1443cdf0e10cSrcweir 1444cdf0e10cSrcweir // skip spaces and commas 1445cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1446cdf0e10cSrcweir 1447cdf0e10cSrcweir // one more point 1448cdf0e10cSrcweir nNumPoints++; 1449cdf0e10cSrcweir } 1450cdf0e10cSrcweir 1451cdf0e10cSrcweir // second loop 1452cdf0e10cSrcweir if(nNumPoints) 1453cdf0e10cSrcweir { 1454cdf0e10cSrcweir nPos = 0; 1455cdf0e10cSrcweir maPoly.realloc(1); 1456cdf0e10cSrcweir drawing::PointSequence* pOuterSequence = maPoly.getArray(); 1457cdf0e10cSrcweir pOuterSequence->realloc(nNumPoints); 1458cdf0e10cSrcweir awt::Point* pInnerSequence = pOuterSequence->getArray(); 1459cdf0e10cSrcweir 1460cdf0e10cSrcweir // object size and ViewBox size different? 1461cdf0e10cSrcweir bool bScale(rObjectSize.Width != rViewBox.GetWidth() 1462cdf0e10cSrcweir || rObjectSize.Height != rViewBox.GetHeight()); 1463cdf0e10cSrcweir bool bTranslate(rViewBox.GetX() != 0L || rViewBox.GetY() != 0L); 1464cdf0e10cSrcweir 1465cdf0e10cSrcweir // skip starting spaces 1466cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 1467cdf0e10cSrcweir 1468cdf0e10cSrcweir while(nPos < nLen) 1469cdf0e10cSrcweir { 1470cdf0e10cSrcweir // prepare new parameter pair 1471cdf0e10cSrcweir sal_Int32 nX(0L); 1472cdf0e10cSrcweir sal_Int32 nY(0L); 1473cdf0e10cSrcweir 1474cdf0e10cSrcweir // get mX, #100617# be prepared for doubles 1475cdf0e10cSrcweir nX = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nX)); 1476cdf0e10cSrcweir 1477cdf0e10cSrcweir // skip spaces and commas 1478cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1479cdf0e10cSrcweir 1480cdf0e10cSrcweir // get mY, #100617# be prepared for doubles 1481cdf0e10cSrcweir nY = FRound(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, (double)nY)); 1482cdf0e10cSrcweir 1483cdf0e10cSrcweir // skip spaces and commas 1484cdf0e10cSrcweir Imp_SkipSpacesAndCommas(aStr, nPos, nLen); 1485cdf0e10cSrcweir 1486cdf0e10cSrcweir // prepare parameters 1487cdf0e10cSrcweir if(bTranslate) 1488cdf0e10cSrcweir { 1489cdf0e10cSrcweir nX -= rViewBox.GetX(); 1490cdf0e10cSrcweir nY -= rViewBox.GetY(); 1491cdf0e10cSrcweir } 1492cdf0e10cSrcweir 1493cdf0e10cSrcweir if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight() ) 1494cdf0e10cSrcweir { 1495cdf0e10cSrcweir nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); 1496cdf0e10cSrcweir nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); 1497cdf0e10cSrcweir } 1498cdf0e10cSrcweir 1499cdf0e10cSrcweir nX += rObjectPos.X; 1500cdf0e10cSrcweir nY += rObjectPos.Y; 1501cdf0e10cSrcweir 1502cdf0e10cSrcweir // add new point 1503cdf0e10cSrcweir *pInnerSequence = awt::Point( nX, nY ); 1504cdf0e10cSrcweir pInnerSequence++; 1505cdf0e10cSrcweir } 1506cdf0e10cSrcweir } 1507cdf0e10cSrcweir } 1508cdf0e10cSrcweir 1509cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1510cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1511cdf0e10cSrcweir 1512cdf0e10cSrcweir SdXMLImExSvgDElement::SdXMLImExSvgDElement(const SdXMLImExViewBox& rViewBox) 1513cdf0e10cSrcweir : mrViewBox( rViewBox ), 1514cdf0e10cSrcweir mbIsClosed( false ), 1515cdf0e10cSrcweir mbIsCurve( false ), 1516cdf0e10cSrcweir mnLastX( 0L ), 1517cdf0e10cSrcweir mnLastY( 0L ), 1518cdf0e10cSrcweir maPoly( 0L ), 1519cdf0e10cSrcweir maFlag( 0L ) 1520cdf0e10cSrcweir { 1521cdf0e10cSrcweir } 1522cdf0e10cSrcweir 1523cdf0e10cSrcweir void Imp_GetPrevPos(awt::Point*& pPrevPos1, 1524cdf0e10cSrcweir drawing::PolygonFlags& aPrevFlag1, 1525cdf0e10cSrcweir const bool bClosed, awt::Point* pPoints, 1526cdf0e10cSrcweir drawing::PolygonFlags* pFlags, const sal_Int32 nPos, 1527cdf0e10cSrcweir const sal_Int32 nCnt, const sal_Int32 nAdd) 1528cdf0e10cSrcweir { 1529cdf0e10cSrcweir if(bClosed) 1530cdf0e10cSrcweir { 1531cdf0e10cSrcweir pPrevPos1 = pPoints + ((nPos + nCnt - nAdd) % nCnt); 1532cdf0e10cSrcweir aPrevFlag1 = *(pFlags + ((nPos + nCnt - nAdd) % nCnt)); 1533cdf0e10cSrcweir } 1534cdf0e10cSrcweir else if(nPos > (nAdd - 1)) 1535cdf0e10cSrcweir { 1536cdf0e10cSrcweir pPrevPos1 = pPoints + (nPos - nAdd); 1537cdf0e10cSrcweir aPrevFlag1 = *(pFlags + (nPos - nAdd)); 1538cdf0e10cSrcweir } 1539cdf0e10cSrcweir else 1540cdf0e10cSrcweir pPrevPos1 = 0L; 1541cdf0e10cSrcweir } 1542cdf0e10cSrcweir 1543cdf0e10cSrcweir void Imp_PrepareCoorExport(sal_Int32& nX, sal_Int32& nY, 1544cdf0e10cSrcweir const awt::Point* pPointArray, const awt::Point& rObjectPos, 1545cdf0e10cSrcweir const awt::Size& rObjectSize, const SdXMLImExViewBox& mrViewBox, 1546cdf0e10cSrcweir const bool bScale, const bool bTranslate) 1547cdf0e10cSrcweir { 1548cdf0e10cSrcweir nX = pPointArray->X - rObjectPos.X; 1549cdf0e10cSrcweir nY = pPointArray->Y - rObjectPos.Y; 1550cdf0e10cSrcweir 1551cdf0e10cSrcweir if(bScale && rObjectSize.Width && rObjectSize.Height ) 1552cdf0e10cSrcweir { 1553cdf0e10cSrcweir nX = (nX * mrViewBox.GetWidth()) / rObjectSize.Width; 1554cdf0e10cSrcweir nY = (nY * mrViewBox.GetHeight()) / rObjectSize.Height; 1555cdf0e10cSrcweir } 1556cdf0e10cSrcweir 1557cdf0e10cSrcweir if(bTranslate) 1558cdf0e10cSrcweir { 1559cdf0e10cSrcweir nX += mrViewBox.GetX(); 1560cdf0e10cSrcweir nY += mrViewBox.GetY(); 1561cdf0e10cSrcweir } 1562cdf0e10cSrcweir } 1563cdf0e10cSrcweir 1564cdf0e10cSrcweir //#define TEST_QUADRATIC_CURVES 1565cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES 1566cdf0e10cSrcweir // To be able to test quadratic curve code: The code concerning to 1567cdf0e10cSrcweir // bDoTestHere can be used (see below). Construct shapes which have their control 1568cdf0e10cSrcweir // points on equal coordinates. When these are written, they can be 1569cdf0e10cSrcweir // forced to create correct 'Q' and 'T' statements using this flag. 1570cdf0e10cSrcweir // These may then be tested for import/exporting. 1571cdf0e10cSrcweir static bool bDoTestHere(true); 1572cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES 1573cdf0e10cSrcweir 1574cdf0e10cSrcweir void SdXMLImExSvgDElement::AddPolygon( 1575cdf0e10cSrcweir drawing::PointSequence* pPoints, 1576cdf0e10cSrcweir drawing::FlagSequence* pFlags, 1577cdf0e10cSrcweir const awt::Point& rObjectPos, 1578cdf0e10cSrcweir const awt::Size& rObjectSize, 1579cdf0e10cSrcweir bool bClosed, bool bRelative) 1580cdf0e10cSrcweir { 1581cdf0e10cSrcweir DBG_ASSERT(pPoints, "Empty PointSequence handed over to SdXMLImExSvgDElement(!)"); 1582cdf0e10cSrcweir 1583cdf0e10cSrcweir sal_Int32 nCnt(pPoints->getLength()); 1584cdf0e10cSrcweir 1585cdf0e10cSrcweir // #104076# Convert to string only when at last one point included 1586cdf0e10cSrcweir if(nCnt > 0) 1587cdf0e10cSrcweir { 1588cdf0e10cSrcweir // append polygon to string 1589cdf0e10cSrcweir OUString aNewString; 1590cdf0e10cSrcweir sal_Unicode aLastCommand = ' '; 1591cdf0e10cSrcweir awt::Point* pPointArray = pPoints->getArray(); 1592cdf0e10cSrcweir 1593cdf0e10cSrcweir // are the flags used at all? If not forget about them 1594cdf0e10cSrcweir if(pFlags) 1595cdf0e10cSrcweir { 1596cdf0e10cSrcweir sal_Int32 nFlagCnt(pFlags->getLength()); 1597cdf0e10cSrcweir 1598cdf0e10cSrcweir if(nFlagCnt) 1599cdf0e10cSrcweir { 1600cdf0e10cSrcweir bool bFlagsUsed(false); 1601cdf0e10cSrcweir drawing::PolygonFlags* pFlagArray = pFlags->getArray(); 1602cdf0e10cSrcweir 1603cdf0e10cSrcweir for(sal_Int32 a(0); !bFlagsUsed && a < nFlagCnt; a++) 1604cdf0e10cSrcweir if(drawing::PolygonFlags_NORMAL != *pFlagArray++) 1605cdf0e10cSrcweir bFlagsUsed = true; 1606cdf0e10cSrcweir 1607cdf0e10cSrcweir if(!bFlagsUsed) 1608cdf0e10cSrcweir pFlags = 0L; 1609cdf0e10cSrcweir } 1610cdf0e10cSrcweir else 1611cdf0e10cSrcweir { 1612cdf0e10cSrcweir pFlags = 0L; 1613cdf0e10cSrcweir } 1614cdf0e10cSrcweir } 1615cdf0e10cSrcweir 1616cdf0e10cSrcweir // object size and ViewBox size different? 1617cdf0e10cSrcweir bool bScale(rObjectSize.Width != mrViewBox.GetWidth() 1618cdf0e10cSrcweir || rObjectSize.Height != mrViewBox.GetHeight()); 1619cdf0e10cSrcweir bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); 1620cdf0e10cSrcweir 1621cdf0e10cSrcweir // #87202# rework of point reduction: 1622cdf0e10cSrcweir // Test for Last point same -> closed, ignore last point. Take 1623cdf0e10cSrcweir // some more circumstances in account when looking at curve segments. 1624cdf0e10cSrcweir drawing::PolygonFlags* pFlagArray = (pFlags) ? pFlags->getArray() : 0L; 1625cdf0e10cSrcweir if((pPointArray->X == (pPointArray + (nCnt - 1))->X) && (pPointArray->Y == (pPointArray + (nCnt - 1))->Y)) 1626cdf0e10cSrcweir { 1627cdf0e10cSrcweir if(pFlags) 1628cdf0e10cSrcweir { 1629cdf0e10cSrcweir // point needs to be ignored if point before it is 1630cdf0e10cSrcweir // NO control point. Else the last point is needed 1631cdf0e10cSrcweir // for exporting the last segment of the curve. That means 1632cdf0e10cSrcweir // that the last and the first point will be saved double, 1633cdf0e10cSrcweir // but SVG does not support a better solution here. 1634cdf0e10cSrcweir if(nCnt >= 2 && drawing::PolygonFlags_CONTROL != *(pFlagArray + (nCnt - 2))) 1635cdf0e10cSrcweir { 1636cdf0e10cSrcweir nCnt--; 1637cdf0e10cSrcweir } 1638cdf0e10cSrcweir } 1639cdf0e10cSrcweir else 1640cdf0e10cSrcweir { 1641cdf0e10cSrcweir // no curve, ignore last point 1642cdf0e10cSrcweir nCnt--; 1643cdf0e10cSrcweir } 1644cdf0e10cSrcweir } 1645cdf0e10cSrcweir 1646cdf0e10cSrcweir // bezier poly, handle curves 1647cdf0e10cSrcweir bool bDidWriteStart(false); 1648cdf0e10cSrcweir 1649cdf0e10cSrcweir for(sal_Int32 a(0L); a < nCnt; a++) 1650cdf0e10cSrcweir { 1651cdf0e10cSrcweir if(!pFlags || drawing::PolygonFlags_CONTROL != *pFlagArray) 1652cdf0e10cSrcweir { 1653cdf0e10cSrcweir bool bDidWriteAsCurve(false); 1654cdf0e10cSrcweir 1655cdf0e10cSrcweir if(bDidWriteStart) 1656cdf0e10cSrcweir { 1657cdf0e10cSrcweir if(pFlags) 1658cdf0e10cSrcweir { 1659cdf0e10cSrcweir // real curve point, get previous to see if it's a control point 1660cdf0e10cSrcweir awt::Point* pPrevPos1; 1661cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag1; 1662cdf0e10cSrcweir 1663cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos1, aPrevFlag1, bClosed, pPoints->getArray(), 1664cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 1); 1665cdf0e10cSrcweir 1666cdf0e10cSrcweir if(pPrevPos1 && drawing::PolygonFlags_CONTROL == aPrevFlag1) 1667cdf0e10cSrcweir { 1668cdf0e10cSrcweir // get previous2 to see if it's a control point, too 1669cdf0e10cSrcweir awt::Point* pPrevPos2; 1670cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag2; 1671cdf0e10cSrcweir 1672cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos2, aPrevFlag2, bClosed, pPoints->getArray(), 1673cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 2); 1674cdf0e10cSrcweir 1675cdf0e10cSrcweir if(pPrevPos2 && drawing::PolygonFlags_CONTROL == aPrevFlag2) 1676cdf0e10cSrcweir { 1677cdf0e10cSrcweir // get previous3 to see if it's a curve point and if, 1678cdf0e10cSrcweir // if it is fully symmetric or not 1679cdf0e10cSrcweir awt::Point* pPrevPos3; 1680cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag3; 1681cdf0e10cSrcweir 1682cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos3, aPrevFlag3, bClosed, pPoints->getArray(), 1683cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 3); 1684cdf0e10cSrcweir 1685cdf0e10cSrcweir if(pPrevPos3) 1686cdf0e10cSrcweir { 1687cdf0e10cSrcweir // prepare coordinates 1688cdf0e10cSrcweir sal_Int32 nX, nY; 1689cdf0e10cSrcweir 1690cdf0e10cSrcweir Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, 1691cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 1692cdf0e10cSrcweir 1693cdf0e10cSrcweir // #100617# test if this curve segment may be written as 1694cdf0e10cSrcweir // a quadratic bezier 1695cdf0e10cSrcweir // That's the case if both control points are in the same place 1696cdf0e10cSrcweir // when they are prolonged to the common quadratic control point 1697cdf0e10cSrcweir // Left: P = (3P1 - P0) / 2 1698cdf0e10cSrcweir // Right: P = (3P2 - P3) / 2 1699cdf0e10cSrcweir bool bIsQuadratic(false); 1700cdf0e10cSrcweir const bool bEnableSaveQuadratic(false); 1701cdf0e10cSrcweir 1702cdf0e10cSrcweir sal_Int32 nPX_L(FRound((double)((3 * pPrevPos2->X) - pPrevPos3->X) / 2.0)); 1703cdf0e10cSrcweir sal_Int32 nPY_L(FRound((double)((3 * pPrevPos2->Y) - pPrevPos3->Y) / 2.0)); 1704cdf0e10cSrcweir sal_Int32 nPX_R(FRound((double)((3 * pPrevPos1->X) - pPointArray->X) / 2.0)); 1705cdf0e10cSrcweir sal_Int32 nPY_R(FRound((double)((3 * pPrevPos1->Y) - pPointArray->Y) / 2.0)); 1706cdf0e10cSrcweir sal_Int32 nDist(0); 1707cdf0e10cSrcweir 1708cdf0e10cSrcweir if(nPX_L != nPX_R) 1709cdf0e10cSrcweir { 1710cdf0e10cSrcweir nDist += abs(nPX_L - nPX_R); 1711cdf0e10cSrcweir } 1712cdf0e10cSrcweir 1713cdf0e10cSrcweir if(nPY_L != nPY_R) 1714cdf0e10cSrcweir { 1715cdf0e10cSrcweir nDist += abs(nPY_L - nPY_R); 1716cdf0e10cSrcweir } 1717cdf0e10cSrcweir 1718cdf0e10cSrcweir if(nDist <= BORDER_INTEGERS_ARE_EQUAL) 1719cdf0e10cSrcweir { 1720cdf0e10cSrcweir if(bEnableSaveQuadratic) 1721cdf0e10cSrcweir { 1722cdf0e10cSrcweir bIsQuadratic = true; 1723cdf0e10cSrcweir } 1724cdf0e10cSrcweir } 1725cdf0e10cSrcweir 1726cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES 1727cdf0e10cSrcweir if(bDoTestHere) 1728cdf0e10cSrcweir { 1729cdf0e10cSrcweir bIsQuadratic = false; 1730cdf0e10cSrcweir 1731cdf0e10cSrcweir if(pPrevPos1->X == pPrevPos2->X && pPrevPos1->Y == pPrevPos2->Y) 1732cdf0e10cSrcweir bIsQuadratic = true; 1733cdf0e10cSrcweir } 1734cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES 1735cdf0e10cSrcweir 1736cdf0e10cSrcweir if(bIsQuadratic) 1737cdf0e10cSrcweir { 1738cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES 1739cdf0e10cSrcweir if(bDoTestHere) 1740cdf0e10cSrcweir { 1741cdf0e10cSrcweir bool bPrevPointIsSymmetric(false); 1742cdf0e10cSrcweir 1743cdf0e10cSrcweir if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) 1744cdf0e10cSrcweir { 1745cdf0e10cSrcweir // get previous4 to see if it's a control point 1746cdf0e10cSrcweir awt::Point* pPrevPos4; 1747cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag4; 1748cdf0e10cSrcweir 1749cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), 1750cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 4); 1751cdf0e10cSrcweir 1752cdf0e10cSrcweir if(drawing::PolygonFlags_CONTROL == aPrevFlag4) 1753cdf0e10cSrcweir { 1754cdf0e10cSrcweir // okay, prevPos3 is symmetric (c2) and prevPos4 1755cdf0e10cSrcweir // is existing control point, the 's' statement can be used 1756cdf0e10cSrcweir bPrevPointIsSymmetric = true; 1757cdf0e10cSrcweir } 1758cdf0e10cSrcweir } 1759cdf0e10cSrcweir 1760cdf0e10cSrcweir if(bPrevPointIsSymmetric) 1761cdf0e10cSrcweir { 1762cdf0e10cSrcweir // write a shorthand/smooth quadratic curveto entry (T) 1763cdf0e10cSrcweir if(bRelative) 1764cdf0e10cSrcweir { 1765cdf0e10cSrcweir if(aLastCommand != sal_Unicode('t')) 1766cdf0e10cSrcweir aNewString += OUString(sal_Unicode('t')); 1767cdf0e10cSrcweir 1768cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1769cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1770cdf0e10cSrcweir 1771cdf0e10cSrcweir aLastCommand = sal_Unicode('t'); 1772cdf0e10cSrcweir } 1773cdf0e10cSrcweir else 1774cdf0e10cSrcweir { 1775cdf0e10cSrcweir if(aLastCommand != sal_Unicode('T')) 1776cdf0e10cSrcweir aNewString += OUString(sal_Unicode('T')); 1777cdf0e10cSrcweir 1778cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 1779cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 1780cdf0e10cSrcweir 1781cdf0e10cSrcweir aLastCommand = sal_Unicode('T'); 1782cdf0e10cSrcweir } 1783cdf0e10cSrcweir } 1784cdf0e10cSrcweir else 1785cdf0e10cSrcweir { 1786cdf0e10cSrcweir // prepare coordinates 1787cdf0e10cSrcweir sal_Int32 nX1, nY1; 1788cdf0e10cSrcweir 1789cdf0e10cSrcweir Imp_PrepareCoorExport(nX1, nY1, pPrevPos1, rObjectPos, rObjectSize, 1790cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 1791cdf0e10cSrcweir 1792cdf0e10cSrcweir // write a quadratic curveto entry (Q) 1793cdf0e10cSrcweir if(bRelative) 1794cdf0e10cSrcweir { 1795cdf0e10cSrcweir if(aLastCommand != sal_Unicode('q')) 1796cdf0e10cSrcweir aNewString += OUString(sal_Unicode('q')); 1797cdf0e10cSrcweir 1798cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); 1799cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); 1800cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1801cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1802cdf0e10cSrcweir 1803cdf0e10cSrcweir aLastCommand = sal_Unicode('q'); 1804cdf0e10cSrcweir } 1805cdf0e10cSrcweir else 1806cdf0e10cSrcweir { 1807cdf0e10cSrcweir if(aLastCommand != sal_Unicode('Q')) 1808cdf0e10cSrcweir aNewString += OUString(sal_Unicode('Q')); 1809cdf0e10cSrcweir 1810cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1); 1811cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1); 1812cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 1813cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 1814cdf0e10cSrcweir 1815cdf0e10cSrcweir aLastCommand = sal_Unicode('Q'); 1816cdf0e10cSrcweir } 1817cdf0e10cSrcweir } 1818cdf0e10cSrcweir } 1819cdf0e10cSrcweir else 1820cdf0e10cSrcweir { 1821cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES 1822cdf0e10cSrcweir awt::Point aNewPoint(nPX_L, nPY_L); 1823cdf0e10cSrcweir bool bPrevPointIsSmooth(false); 1824cdf0e10cSrcweir 1825cdf0e10cSrcweir if(drawing::PolygonFlags_SMOOTH == aPrevFlag3) 1826cdf0e10cSrcweir { 1827cdf0e10cSrcweir // get previous4 to see if it's a control point 1828cdf0e10cSrcweir awt::Point* pPrevPos4; 1829cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag4; 1830cdf0e10cSrcweir 1831cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), 1832cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 4); 1833cdf0e10cSrcweir 1834cdf0e10cSrcweir if(drawing::PolygonFlags_CONTROL == aPrevFlag4) 1835cdf0e10cSrcweir { 1836cdf0e10cSrcweir // okay, prevPos3 is smooth (c1) and prevPos4 1837cdf0e10cSrcweir // is existing control point. Test if it's even symmetric 1838cdf0e10cSrcweir // and thus the 'T' statement may be used. 1839cdf0e10cSrcweir ::basegfx::B2DVector aVec1(pPrevPos4->X - pPrevPos3->X, pPrevPos4->Y - pPrevPos3->Y); 1840cdf0e10cSrcweir ::basegfx::B2DVector aVec2(aNewPoint.X - pPrevPos3->X, aNewPoint.Y - pPrevPos3->Y); 1841cdf0e10cSrcweir bool bSameLength(false); 1842cdf0e10cSrcweir bool bSameDirection(false); 1843cdf0e10cSrcweir 1844cdf0e10cSrcweir // get vector values 1845cdf0e10cSrcweir Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); 1846cdf0e10cSrcweir 1847cdf0e10cSrcweir if(bSameLength && bSameDirection) 1848cdf0e10cSrcweir bPrevPointIsSmooth = true; 1849cdf0e10cSrcweir } 1850cdf0e10cSrcweir } 1851cdf0e10cSrcweir 1852cdf0e10cSrcweir if(bPrevPointIsSmooth) 1853cdf0e10cSrcweir { 1854cdf0e10cSrcweir // write a shorthand/smooth quadratic curveto entry (T) 1855cdf0e10cSrcweir if(bRelative) 1856cdf0e10cSrcweir { 1857cdf0e10cSrcweir if(aLastCommand != sal_Unicode('t')) 1858cdf0e10cSrcweir aNewString += String(sal_Unicode('t')); 1859cdf0e10cSrcweir 1860cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1861cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1862cdf0e10cSrcweir 1863cdf0e10cSrcweir aLastCommand = sal_Unicode('t'); 1864cdf0e10cSrcweir } 1865cdf0e10cSrcweir else 1866cdf0e10cSrcweir { 1867cdf0e10cSrcweir if(aLastCommand != sal_Unicode('T')) 1868cdf0e10cSrcweir aNewString += String(sal_Unicode('T')); 1869cdf0e10cSrcweir 1870cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 1871cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 1872cdf0e10cSrcweir 1873cdf0e10cSrcweir aLastCommand = sal_Unicode('T'); 1874cdf0e10cSrcweir } 1875cdf0e10cSrcweir } 1876cdf0e10cSrcweir else 1877cdf0e10cSrcweir { 1878cdf0e10cSrcweir // prepare coordinates 1879cdf0e10cSrcweir sal_Int32 nX1, nY1; 1880cdf0e10cSrcweir 1881cdf0e10cSrcweir Imp_PrepareCoorExport(nX1, nY1, &aNewPoint, rObjectPos, rObjectSize, 1882cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 1883cdf0e10cSrcweir 1884cdf0e10cSrcweir // write a quadratic curveto entry (Q) 1885cdf0e10cSrcweir if(bRelative) 1886cdf0e10cSrcweir { 1887cdf0e10cSrcweir if(aLastCommand != sal_Unicode('q')) 1888cdf0e10cSrcweir aNewString += String(sal_Unicode('q')); 1889cdf0e10cSrcweir 1890cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); 1891cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); 1892cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1893cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1894cdf0e10cSrcweir 1895cdf0e10cSrcweir aLastCommand = sal_Unicode('q'); 1896cdf0e10cSrcweir } 1897cdf0e10cSrcweir else 1898cdf0e10cSrcweir { 1899cdf0e10cSrcweir if(aLastCommand != sal_Unicode('Q')) 1900cdf0e10cSrcweir aNewString += String(sal_Unicode('Q')); 1901cdf0e10cSrcweir 1902cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1); 1903cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1); 1904cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 1905cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 1906cdf0e10cSrcweir 1907cdf0e10cSrcweir aLastCommand = sal_Unicode('Q'); 1908cdf0e10cSrcweir } 1909cdf0e10cSrcweir } 1910cdf0e10cSrcweir #ifdef TEST_QUADRATIC_CURVES 1911cdf0e10cSrcweir } 1912cdf0e10cSrcweir #endif // TEST_QUADRATIC_CURVES 1913cdf0e10cSrcweir } 1914cdf0e10cSrcweir else 1915cdf0e10cSrcweir { 1916cdf0e10cSrcweir bool bPrevPointIsSymmetric(false); 1917cdf0e10cSrcweir 1918cdf0e10cSrcweir if(drawing::PolygonFlags_SYMMETRIC == aPrevFlag3) 1919cdf0e10cSrcweir { 1920cdf0e10cSrcweir // get previous4 to see if it's a control point 1921cdf0e10cSrcweir awt::Point* pPrevPos4; 1922cdf0e10cSrcweir drawing::PolygonFlags aPrevFlag4; 1923cdf0e10cSrcweir 1924cdf0e10cSrcweir Imp_GetPrevPos(pPrevPos4, aPrevFlag4, bClosed, pPoints->getArray(), 1925cdf0e10cSrcweir pFlags->getArray(), a, nCnt, 4); 1926cdf0e10cSrcweir 1927cdf0e10cSrcweir if(drawing::PolygonFlags_CONTROL == aPrevFlag4) 1928cdf0e10cSrcweir { 1929cdf0e10cSrcweir // okay, prevPos3 is symmetric (c2) and prevPos4 1930cdf0e10cSrcweir // is existing control point, the 's' statement can be used 1931cdf0e10cSrcweir bPrevPointIsSymmetric = true; 1932cdf0e10cSrcweir } 1933cdf0e10cSrcweir } 1934cdf0e10cSrcweir 1935cdf0e10cSrcweir // prepare coordinates 1936cdf0e10cSrcweir sal_Int32 nX2, nY2; 1937cdf0e10cSrcweir 1938cdf0e10cSrcweir Imp_PrepareCoorExport(nX2, nY2, pPrevPos1, rObjectPos, rObjectSize, 1939cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 1940cdf0e10cSrcweir 1941cdf0e10cSrcweir if(bPrevPointIsSymmetric) 1942cdf0e10cSrcweir { 1943cdf0e10cSrcweir // write a shorthand/smooth curveto entry (S) 1944cdf0e10cSrcweir if(bRelative) 1945cdf0e10cSrcweir { 1946cdf0e10cSrcweir if(aLastCommand != sal_Unicode('s')) 1947cdf0e10cSrcweir aNewString += String(sal_Unicode('s')); 1948cdf0e10cSrcweir 1949cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); 1950cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); 1951cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1952cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1953cdf0e10cSrcweir 1954cdf0e10cSrcweir aLastCommand = sal_Unicode('s'); 1955cdf0e10cSrcweir } 1956cdf0e10cSrcweir else 1957cdf0e10cSrcweir { 1958cdf0e10cSrcweir if(aLastCommand != sal_Unicode('S')) 1959cdf0e10cSrcweir aNewString += String(sal_Unicode('S')); 1960cdf0e10cSrcweir 1961cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX2); 1962cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY2); 1963cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 1964cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 1965cdf0e10cSrcweir 1966cdf0e10cSrcweir aLastCommand = sal_Unicode('S'); 1967cdf0e10cSrcweir } 1968cdf0e10cSrcweir } 1969cdf0e10cSrcweir else 1970cdf0e10cSrcweir { 1971cdf0e10cSrcweir // prepare coordinates 1972cdf0e10cSrcweir sal_Int32 nX1, nY1; 1973cdf0e10cSrcweir 1974cdf0e10cSrcweir Imp_PrepareCoorExport(nX1, nY1, pPrevPos2, rObjectPos, rObjectSize, 1975cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 1976cdf0e10cSrcweir 1977cdf0e10cSrcweir // write a curveto entry (C) 1978cdf0e10cSrcweir if(bRelative) 1979cdf0e10cSrcweir { 1980cdf0e10cSrcweir if(aLastCommand != sal_Unicode('c')) 1981cdf0e10cSrcweir aNewString += String(sal_Unicode('c')); 1982cdf0e10cSrcweir 1983cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1 - mnLastX); 1984cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1 - mnLastY); 1985cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX2 - mnLastX); 1986cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY2 - mnLastY); 1987cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 1988cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 1989cdf0e10cSrcweir 1990cdf0e10cSrcweir aLastCommand = sal_Unicode('c'); 1991cdf0e10cSrcweir } 1992cdf0e10cSrcweir else 1993cdf0e10cSrcweir { 1994cdf0e10cSrcweir if(aLastCommand != sal_Unicode('C')) 1995cdf0e10cSrcweir aNewString += String(sal_Unicode('C')); 1996cdf0e10cSrcweir 1997cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX1); 1998cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY1); 1999cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX2); 2000cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY2); 2001cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 2002cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 2003cdf0e10cSrcweir 2004cdf0e10cSrcweir aLastCommand = sal_Unicode('C'); 2005cdf0e10cSrcweir } 2006cdf0e10cSrcweir } 2007cdf0e10cSrcweir } 2008cdf0e10cSrcweir 2009cdf0e10cSrcweir // remember that current point IS written 2010cdf0e10cSrcweir bDidWriteAsCurve = true; 2011cdf0e10cSrcweir 2012cdf0e10cSrcweir // remember new last position 2013cdf0e10cSrcweir mnLastX = nX; 2014cdf0e10cSrcweir mnLastY = nY; 2015cdf0e10cSrcweir } 2016cdf0e10cSrcweir } 2017cdf0e10cSrcweir } 2018cdf0e10cSrcweir } 2019cdf0e10cSrcweir } 2020cdf0e10cSrcweir 2021cdf0e10cSrcweir if(!bDidWriteAsCurve) 2022cdf0e10cSrcweir { 2023cdf0e10cSrcweir // current point not yet written, prepare coordinates 2024cdf0e10cSrcweir sal_Int32 nX, nY; 2025cdf0e10cSrcweir 2026cdf0e10cSrcweir Imp_PrepareCoorExport(nX, nY, pPointArray, rObjectPos, rObjectSize, 2027cdf0e10cSrcweir mrViewBox, bScale, bTranslate); 2028cdf0e10cSrcweir 2029cdf0e10cSrcweir if(bDidWriteStart) 2030cdf0e10cSrcweir { 2031cdf0e10cSrcweir // write as normal point 2032cdf0e10cSrcweir if(mnLastX == nX) 2033cdf0e10cSrcweir { 2034cdf0e10cSrcweir if(bRelative) 2035cdf0e10cSrcweir { 2036cdf0e10cSrcweir if(aLastCommand != sal_Unicode('v')) 2037cdf0e10cSrcweir aNewString += String(sal_Unicode('v')); 2038cdf0e10cSrcweir 2039cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 2040cdf0e10cSrcweir 2041cdf0e10cSrcweir aLastCommand = sal_Unicode('v'); 2042cdf0e10cSrcweir } 2043cdf0e10cSrcweir else 2044cdf0e10cSrcweir { 2045cdf0e10cSrcweir if(aLastCommand != sal_Unicode('V')) 2046cdf0e10cSrcweir aNewString += String(sal_Unicode('V')); 2047cdf0e10cSrcweir 2048cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 2049cdf0e10cSrcweir 2050cdf0e10cSrcweir aLastCommand = sal_Unicode('V'); 2051cdf0e10cSrcweir } 2052cdf0e10cSrcweir } 2053cdf0e10cSrcweir else if(mnLastY == nY) 2054cdf0e10cSrcweir { 2055cdf0e10cSrcweir if(bRelative) 2056cdf0e10cSrcweir { 2057cdf0e10cSrcweir if(aLastCommand != sal_Unicode('h')) 2058cdf0e10cSrcweir aNewString += String(sal_Unicode('h')); 2059cdf0e10cSrcweir 2060cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 2061cdf0e10cSrcweir 2062cdf0e10cSrcweir aLastCommand = sal_Unicode('h'); 2063cdf0e10cSrcweir } 2064cdf0e10cSrcweir else 2065cdf0e10cSrcweir { 2066cdf0e10cSrcweir if(aLastCommand != sal_Unicode('H')) 2067cdf0e10cSrcweir aNewString += String(sal_Unicode('H')); 2068cdf0e10cSrcweir 2069cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 2070cdf0e10cSrcweir 2071cdf0e10cSrcweir aLastCommand = sal_Unicode('H'); 2072cdf0e10cSrcweir } 2073cdf0e10cSrcweir } 2074cdf0e10cSrcweir else 2075cdf0e10cSrcweir { 2076cdf0e10cSrcweir if(bRelative) 2077cdf0e10cSrcweir { 2078cdf0e10cSrcweir if(aLastCommand != sal_Unicode('l')) 2079cdf0e10cSrcweir aNewString += String(sal_Unicode('l')); 2080cdf0e10cSrcweir 2081cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 2082cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 2083cdf0e10cSrcweir 2084cdf0e10cSrcweir aLastCommand = sal_Unicode('l'); 2085cdf0e10cSrcweir } 2086cdf0e10cSrcweir else 2087cdf0e10cSrcweir { 2088cdf0e10cSrcweir if(aLastCommand != sal_Unicode('L')) 2089cdf0e10cSrcweir aNewString += String(sal_Unicode('L')); 2090cdf0e10cSrcweir 2091cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 2092cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 2093cdf0e10cSrcweir 2094cdf0e10cSrcweir aLastCommand = sal_Unicode('L'); 2095cdf0e10cSrcweir } 2096cdf0e10cSrcweir } 2097cdf0e10cSrcweir } 2098cdf0e10cSrcweir else 2099cdf0e10cSrcweir { 2100cdf0e10cSrcweir // write as start point 2101cdf0e10cSrcweir if(bRelative) 2102cdf0e10cSrcweir { 2103cdf0e10cSrcweir aNewString += String(sal_Unicode('m')); 2104cdf0e10cSrcweir 2105cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX - mnLastX); 2106cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY - mnLastY); 2107cdf0e10cSrcweir 2108cdf0e10cSrcweir aLastCommand = sal_Unicode('l'); 2109cdf0e10cSrcweir } 2110cdf0e10cSrcweir else 2111cdf0e10cSrcweir { 2112cdf0e10cSrcweir aNewString += String(sal_Unicode('M')); 2113cdf0e10cSrcweir 2114cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nX); 2115cdf0e10cSrcweir Imp_PutNumberCharWithSpace(aNewString, nY); 2116cdf0e10cSrcweir 2117cdf0e10cSrcweir aLastCommand = sal_Unicode('L'); 2118cdf0e10cSrcweir } 2119cdf0e10cSrcweir 2120cdf0e10cSrcweir // remember start written 2121cdf0e10cSrcweir bDidWriteStart = true; 2122cdf0e10cSrcweir } 2123cdf0e10cSrcweir 2124cdf0e10cSrcweir // remember new last position 2125cdf0e10cSrcweir mnLastX = nX; 2126cdf0e10cSrcweir mnLastY = nY; 2127cdf0e10cSrcweir } 2128cdf0e10cSrcweir } 2129cdf0e10cSrcweir 2130cdf0e10cSrcweir // next point 2131cdf0e10cSrcweir pPointArray++; 2132cdf0e10cSrcweir pFlagArray++; 2133cdf0e10cSrcweir } 2134cdf0e10cSrcweir 2135cdf0e10cSrcweir // close path if closed poly 2136cdf0e10cSrcweir if(bClosed) 2137cdf0e10cSrcweir { 2138cdf0e10cSrcweir if(bRelative) 2139cdf0e10cSrcweir aNewString += String(sal_Unicode('z')); 2140cdf0e10cSrcweir else 2141cdf0e10cSrcweir aNewString += String(sal_Unicode('Z')); 2142cdf0e10cSrcweir } 2143cdf0e10cSrcweir 2144cdf0e10cSrcweir // append new string 2145cdf0e10cSrcweir msString += aNewString; 2146cdf0e10cSrcweir } 2147cdf0e10cSrcweir } 2148cdf0e10cSrcweir 2149cdf0e10cSrcweir // #100617# Linear double reader 2150cdf0e10cSrcweir double Imp_ImportDoubleAndSpaces( 2151cdf0e10cSrcweir double fRetval, const OUString& rStr, sal_Int32& rPos, 2152cdf0e10cSrcweir const sal_Int32 nLen, const SvXMLUnitConverter& rConv) 2153cdf0e10cSrcweir { 2154cdf0e10cSrcweir fRetval = Imp_GetDoubleChar(rStr, rPos, nLen, rConv, fRetval); 2155cdf0e10cSrcweir Imp_SkipSpacesAndCommas(rStr, rPos, nLen); 2156cdf0e10cSrcweir return fRetval; 2157cdf0e10cSrcweir } 2158cdf0e10cSrcweir 2159cdf0e10cSrcweir // #100617# Allow to read doubles, too. This will need to be changed to 2160cdf0e10cSrcweir // the usage of Imp_ImportDoubleAndSpaces(...). For now, this is sufficient 2161cdf0e10cSrcweir // since the interface cannot transport doubles. 2162cdf0e10cSrcweir sal_Int32 Imp_ImportNumberAndSpaces( 2163cdf0e10cSrcweir sal_Int32 nRetval, const OUString& rStr, sal_Int32& rPos, 2164cdf0e10cSrcweir const sal_Int32 nLen, const SvXMLUnitConverter& rConv) 2165cdf0e10cSrcweir { 2166cdf0e10cSrcweir nRetval = FRound(Imp_ImportDoubleAndSpaces(double(nRetval), rStr, rPos, nLen, rConv)); 2167cdf0e10cSrcweir Imp_SkipSpacesAndCommas(rStr, rPos, nLen); 2168cdf0e10cSrcweir return nRetval; 2169cdf0e10cSrcweir } 2170cdf0e10cSrcweir 2171cdf0e10cSrcweir void Imp_PrepareCoorImport(sal_Int32& nX, sal_Int32& nY, 2172cdf0e10cSrcweir const awt::Point& rObjectPos, const awt::Size& rObjectSize, 2173cdf0e10cSrcweir const SdXMLImExViewBox& rViewBox, const bool bScale, const bool bTranslate) 2174cdf0e10cSrcweir { 2175cdf0e10cSrcweir if(bTranslate) 2176cdf0e10cSrcweir { 2177cdf0e10cSrcweir nX -= rViewBox.GetX(); 2178cdf0e10cSrcweir nY -= rViewBox.GetY(); 2179cdf0e10cSrcweir } 2180cdf0e10cSrcweir 2181cdf0e10cSrcweir if(bScale && rViewBox.GetWidth() && rViewBox.GetHeight()) 2182cdf0e10cSrcweir { 2183cdf0e10cSrcweir nX = (nX * rObjectSize.Width) / rViewBox.GetWidth(); 2184cdf0e10cSrcweir nY = (nY * rObjectSize.Height) / rViewBox.GetHeight(); 2185cdf0e10cSrcweir } 2186cdf0e10cSrcweir 2187cdf0e10cSrcweir nX += rObjectPos.X; 2188cdf0e10cSrcweir nY += rObjectPos.Y; 2189cdf0e10cSrcweir } 2190cdf0e10cSrcweir 2191cdf0e10cSrcweir void Imp_AddExportPoints(sal_Int32 nX, sal_Int32 nY, 2192cdf0e10cSrcweir awt::Point* pPoints, drawing::PolygonFlags* pFlags, 2193cdf0e10cSrcweir const sal_Int32 nInnerIndex, 2194cdf0e10cSrcweir drawing::PolygonFlags eFlag) 2195cdf0e10cSrcweir { 2196cdf0e10cSrcweir if(pPoints) 2197cdf0e10cSrcweir pPoints[nInnerIndex] = awt::Point( nX, nY ); 2198cdf0e10cSrcweir 2199cdf0e10cSrcweir if(pFlags) 2200cdf0e10cSrcweir pFlags[nInnerIndex] = eFlag; 2201cdf0e10cSrcweir } 2202cdf0e10cSrcweir 2203cdf0e10cSrcweir void Imp_CalcVectorValues(::basegfx::B2DVector& aVec1, ::basegfx::B2DVector& aVec2, bool& bSameLength, bool& bSameDirection) 2204cdf0e10cSrcweir { 2205cdf0e10cSrcweir const sal_Int32 nLen1(FRound(aVec1.getLength())); 2206cdf0e10cSrcweir const sal_Int32 nLen2(FRound(aVec2.getLength())); 2207cdf0e10cSrcweir aVec1.normalize(); 2208cdf0e10cSrcweir aVec2.normalize(); 2209cdf0e10cSrcweir aVec1 += aVec2; 2210cdf0e10cSrcweir const sal_Int32 nLen3(FRound(aVec1.getLength() * ((nLen1 + nLen2) / 2.0))); 2211cdf0e10cSrcweir 2212cdf0e10cSrcweir bSameLength = (abs(nLen1 - nLen2) <= BORDER_INTEGERS_ARE_EQUAL); 2213cdf0e10cSrcweir bSameDirection = (nLen3 <= BORDER_INTEGERS_ARE_EQUAL); 2214cdf0e10cSrcweir } 2215cdf0e10cSrcweir 2216cdf0e10cSrcweir void Imp_CorrectPolygonFlag(const sal_uInt32 nInnerIndex, const awt::Point* const pInnerSequence, 2217cdf0e10cSrcweir drawing::PolygonFlags* const pInnerFlags, const sal_Int32 nX1, const sal_Int32 nY1) 2218cdf0e10cSrcweir { 2219cdf0e10cSrcweir if(nInnerIndex) 2220cdf0e10cSrcweir { 2221cdf0e10cSrcweir const awt::Point aPPrev1 = pInnerSequence[nInnerIndex - 1]; 2222cdf0e10cSrcweir 2223cdf0e10cSrcweir if(nInnerIndex > 1) 2224cdf0e10cSrcweir { 2225cdf0e10cSrcweir const awt::Point aPPrev2 = pInnerSequence[nInnerIndex - 2]; 2226cdf0e10cSrcweir const drawing::PolygonFlags aFPrev2 = pInnerFlags[nInnerIndex - 2]; 2227cdf0e10cSrcweir ::basegfx::B2DVector aVec1(aPPrev2.X - aPPrev1.X, aPPrev2.Y - aPPrev1.Y); 2228cdf0e10cSrcweir ::basegfx::B2DVector aVec2(nX1 - aPPrev1.X, nY1 - aPPrev1.Y); 2229cdf0e10cSrcweir bool bSameLength(false); 2230cdf0e10cSrcweir bool bSameDirection(false); 2231cdf0e10cSrcweir 2232cdf0e10cSrcweir // get vector values 2233cdf0e10cSrcweir Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); 2234cdf0e10cSrcweir 2235cdf0e10cSrcweir if(drawing::PolygonFlags_CONTROL == aFPrev2) 2236cdf0e10cSrcweir { 2237cdf0e10cSrcweir // point before is a control point 2238cdf0e10cSrcweir if(bSameDirection) 2239cdf0e10cSrcweir { 2240cdf0e10cSrcweir if(bSameLength) 2241cdf0e10cSrcweir { 2242cdf0e10cSrcweir // set to PolygonFlags_SYMMETRIC 2243cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; 2244cdf0e10cSrcweir } 2245cdf0e10cSrcweir else 2246cdf0e10cSrcweir { 2247cdf0e10cSrcweir // set to PolygonFlags_SMOOTH 2248cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; 2249cdf0e10cSrcweir } 2250cdf0e10cSrcweir } 2251cdf0e10cSrcweir else 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir // set to PolygonFlags_NORMAL 2254cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; 2255cdf0e10cSrcweir } 2256cdf0e10cSrcweir } 2257cdf0e10cSrcweir else 2258cdf0e10cSrcweir { 2259cdf0e10cSrcweir // point before is a simple curve point 2260cdf0e10cSrcweir if(bSameDirection) 2261cdf0e10cSrcweir { 2262cdf0e10cSrcweir // set to PolygonFlags_SMOOTH 2263cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; 2264cdf0e10cSrcweir } 2265cdf0e10cSrcweir else 2266cdf0e10cSrcweir { 2267cdf0e10cSrcweir // set to PolygonFlags_NORMAL 2268cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; 2269cdf0e10cSrcweir } 2270cdf0e10cSrcweir } 2271cdf0e10cSrcweir } 2272cdf0e10cSrcweir else 2273cdf0e10cSrcweir { 2274cdf0e10cSrcweir // no point before starpoint, set type to PolygonFlags_NORMAL 2275cdf0e10cSrcweir pInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_NORMAL; 2276cdf0e10cSrcweir } 2277cdf0e10cSrcweir } 2278cdf0e10cSrcweir } 2279cdf0e10cSrcweir 2280cdf0e10cSrcweir SdXMLImExSvgDElement::SdXMLImExSvgDElement(const OUString& rNew, 2281cdf0e10cSrcweir const SdXMLImExViewBox& rViewBox, 2282cdf0e10cSrcweir const awt::Point& rObjectPos, 2283cdf0e10cSrcweir const awt::Size& rObjectSize, 2284cdf0e10cSrcweir const SvXMLUnitConverter& rConv) 2285cdf0e10cSrcweir : msString( rNew ), 2286cdf0e10cSrcweir mrViewBox( rViewBox ), 2287cdf0e10cSrcweir mbIsClosed( false ), 2288cdf0e10cSrcweir mbIsCurve( false ), 2289cdf0e10cSrcweir mnLastX( 0L ), 2290cdf0e10cSrcweir mnLastY( 0L ), 2291cdf0e10cSrcweir maPoly( 0L ), 2292cdf0e10cSrcweir maFlag( 0L ) 2293cdf0e10cSrcweir { 2294cdf0e10cSrcweir // convert string to polygon 2295cdf0e10cSrcweir const OUString aStr(msString.getStr(), msString.getLength()); 2296cdf0e10cSrcweir const sal_Int32 nLen(aStr.getLength()); 2297cdf0e10cSrcweir sal_Int32 nPos(0); 2298cdf0e10cSrcweir sal_Int32 nNumPolys(0L); 2299cdf0e10cSrcweir bool bEllipticalArc(false); 2300cdf0e10cSrcweir 2301cdf0e10cSrcweir // object size and ViewBox size different? 2302cdf0e10cSrcweir bool bScale(rObjectSize.Width != mrViewBox.GetWidth() 2303cdf0e10cSrcweir || rObjectSize.Height != mrViewBox.GetHeight()); 2304cdf0e10cSrcweir bool bTranslate(mrViewBox.GetX() != 0L || mrViewBox.GetY() != 0L); 2305cdf0e10cSrcweir 2306cdf0e10cSrcweir // first loop: count polys and get flags 2307cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2308cdf0e10cSrcweir 2309cdf0e10cSrcweir while(nPos < nLen) 2310cdf0e10cSrcweir { 2311cdf0e10cSrcweir switch(aStr[nPos++]) 2312cdf0e10cSrcweir { 2313cdf0e10cSrcweir case 'Z' : 2314cdf0e10cSrcweir case 'z' : 2315cdf0e10cSrcweir { 2316cdf0e10cSrcweir break; 2317cdf0e10cSrcweir } 2318cdf0e10cSrcweir case 'M' : 2319cdf0e10cSrcweir case 'm' : 2320cdf0e10cSrcweir { 2321cdf0e10cSrcweir nNumPolys++; 2322cdf0e10cSrcweir break; 2323cdf0e10cSrcweir } 2324cdf0e10cSrcweir case 'S' : 2325cdf0e10cSrcweir case 's' : 2326cdf0e10cSrcweir case 'C' : 2327cdf0e10cSrcweir case 'c' : 2328cdf0e10cSrcweir case 'Q' : 2329cdf0e10cSrcweir case 'q' : 2330cdf0e10cSrcweir case 'T' : 2331cdf0e10cSrcweir case 't' : 2332cdf0e10cSrcweir { 2333cdf0e10cSrcweir mbIsCurve = true; 2334cdf0e10cSrcweir break; 2335cdf0e10cSrcweir } 2336cdf0e10cSrcweir case 'L' : 2337cdf0e10cSrcweir case 'l' : 2338cdf0e10cSrcweir case 'H' : 2339cdf0e10cSrcweir case 'h' : 2340cdf0e10cSrcweir case 'V' : 2341cdf0e10cSrcweir case 'v' : 2342cdf0e10cSrcweir { 2343cdf0e10cSrcweir // normal, interpreted values. All okay. 2344cdf0e10cSrcweir break; 2345cdf0e10cSrcweir } 2346cdf0e10cSrcweir case 'A' : 2347cdf0e10cSrcweir case 'a' : 2348cdf0e10cSrcweir { 2349cdf0e10cSrcweir // Not yet interpreted value. 2350cdf0e10cSrcweir bEllipticalArc = true; 2351cdf0e10cSrcweir break; 2352cdf0e10cSrcweir } 2353cdf0e10cSrcweir } 2354cdf0e10cSrcweir } 2355cdf0e10cSrcweir 2356cdf0e10cSrcweir DBG_ASSERT(!bEllipticalArc, "XMLIMP: non-interpreted tags in svg:d element!"); 2357cdf0e10cSrcweir 2358cdf0e10cSrcweir if(nNumPolys) 2359cdf0e10cSrcweir { 2360cdf0e10cSrcweir // alloc arrays 2361cdf0e10cSrcweir maPoly.realloc(nNumPolys); 2362cdf0e10cSrcweir if(IsCurve()) 2363cdf0e10cSrcweir maFlag.realloc(nNumPolys); 2364cdf0e10cSrcweir 2365cdf0e10cSrcweir // get outer sequences 2366cdf0e10cSrcweir drawing::PointSequence* pOuterSequence = maPoly.getArray(); 2367cdf0e10cSrcweir drawing::FlagSequence* pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; 2368cdf0e10cSrcweir 2369cdf0e10cSrcweir // prepare new loop, count 2370cdf0e10cSrcweir sal_uInt32 nPointCount(0L); 2371cdf0e10cSrcweir nPos = 0; 2372cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2373cdf0e10cSrcweir 2374cdf0e10cSrcweir // #104076# reset closed flag for next to be started polygon 2375cdf0e10cSrcweir mbIsClosed = false; 2376cdf0e10cSrcweir 2377cdf0e10cSrcweir while(nPos < nLen) 2378cdf0e10cSrcweir { 2379cdf0e10cSrcweir switch(aStr[nPos]) 2380cdf0e10cSrcweir { 2381cdf0e10cSrcweir case 'z' : 2382cdf0e10cSrcweir case 'Z' : 2383cdf0e10cSrcweir { 2384cdf0e10cSrcweir nPos++; 2385cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2386cdf0e10cSrcweir 2387cdf0e10cSrcweir // #104076# remember closed state of current polygon 2388cdf0e10cSrcweir mbIsClosed = true; 2389cdf0e10cSrcweir 2390cdf0e10cSrcweir break; 2391cdf0e10cSrcweir } 2392cdf0e10cSrcweir case 'm' : 2393cdf0e10cSrcweir case 'M' : 2394cdf0e10cSrcweir { 2395cdf0e10cSrcweir // new poly starts, end-process current poly 2396cdf0e10cSrcweir if(nPointCount) 2397cdf0e10cSrcweir { 2398cdf0e10cSrcweir // #104076# If this partial polygon is closed, use one more point 2399cdf0e10cSrcweir // to represent that 2400cdf0e10cSrcweir if(mbIsClosed) 2401cdf0e10cSrcweir { 2402cdf0e10cSrcweir nPointCount++; 2403cdf0e10cSrcweir } 2404cdf0e10cSrcweir 2405cdf0e10cSrcweir pOuterSequence->realloc(nPointCount); 2406cdf0e10cSrcweir pOuterSequence++; 2407cdf0e10cSrcweir 2408cdf0e10cSrcweir if(pOuterFlags) 2409cdf0e10cSrcweir { 2410cdf0e10cSrcweir pOuterFlags->realloc(nPointCount); 2411cdf0e10cSrcweir pOuterFlags++; 2412cdf0e10cSrcweir } 2413cdf0e10cSrcweir 2414cdf0e10cSrcweir // reset point count for next polygon 2415cdf0e10cSrcweir nPointCount = 0L; 2416cdf0e10cSrcweir } 2417cdf0e10cSrcweir 2418cdf0e10cSrcweir // #104076# reset closed flag for next to be started polygon 2419cdf0e10cSrcweir mbIsClosed = false; 2420cdf0e10cSrcweir 2421cdf0e10cSrcweir // NO break, continue in next case 2422cdf0e10cSrcweir } 2423cdf0e10cSrcweir case 'L' : 2424cdf0e10cSrcweir case 'l' : 2425cdf0e10cSrcweir { 2426cdf0e10cSrcweir nPos++; 2427cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2428cdf0e10cSrcweir 2429cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2430cdf0e10cSrcweir { 2431cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2432cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2433cdf0e10cSrcweir nPointCount++; 2434cdf0e10cSrcweir } 2435cdf0e10cSrcweir break; 2436cdf0e10cSrcweir } 2437cdf0e10cSrcweir case 'H' : 2438cdf0e10cSrcweir case 'h' : 2439cdf0e10cSrcweir case 'V' : 2440cdf0e10cSrcweir case 'v' : 2441cdf0e10cSrcweir { 2442cdf0e10cSrcweir nPos++; 2443cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2444cdf0e10cSrcweir 2445cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2446cdf0e10cSrcweir { 2447cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2448cdf0e10cSrcweir nPointCount++; 2449cdf0e10cSrcweir } 2450cdf0e10cSrcweir break; 2451cdf0e10cSrcweir } 2452cdf0e10cSrcweir case 'S' : 2453cdf0e10cSrcweir case 's' : 2454cdf0e10cSrcweir { 2455cdf0e10cSrcweir nPos++; 2456cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2457cdf0e10cSrcweir 2458cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2459cdf0e10cSrcweir { 2460cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2461cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2462cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2463cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2464cdf0e10cSrcweir nPointCount += 3; 2465cdf0e10cSrcweir } 2466cdf0e10cSrcweir break; 2467cdf0e10cSrcweir } 2468cdf0e10cSrcweir case 'C' : 2469cdf0e10cSrcweir case 'c' : 2470cdf0e10cSrcweir { 2471cdf0e10cSrcweir nPos++; 2472cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2473cdf0e10cSrcweir 2474cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2475cdf0e10cSrcweir { 2476cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2477cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2478cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2479cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2480cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2481cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2482cdf0e10cSrcweir nPointCount += 3; 2483cdf0e10cSrcweir } 2484cdf0e10cSrcweir break; 2485cdf0e10cSrcweir } 2486cdf0e10cSrcweir 2487cdf0e10cSrcweir // #100617# quadratic beziers, supported as cubic ones 2488cdf0e10cSrcweir case 'Q' : 2489cdf0e10cSrcweir case 'q' : 2490cdf0e10cSrcweir { 2491cdf0e10cSrcweir nPos++; 2492cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2493cdf0e10cSrcweir 2494cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2495cdf0e10cSrcweir { 2496cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2497cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2498cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2499cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2500cdf0e10cSrcweir 2501cdf0e10cSrcweir // use three points since quadratic is imported as cubic 2502cdf0e10cSrcweir nPointCount += 3; 2503cdf0e10cSrcweir } 2504cdf0e10cSrcweir break; 2505cdf0e10cSrcweir } 2506cdf0e10cSrcweir 2507cdf0e10cSrcweir // #100617# relative quadratic beziers, supported as cubic ones 2508cdf0e10cSrcweir case 'T' : 2509cdf0e10cSrcweir case 't' : 2510cdf0e10cSrcweir { 2511cdf0e10cSrcweir nPos++; 2512cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2513cdf0e10cSrcweir 2514cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2515cdf0e10cSrcweir { 2516cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2517cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2518cdf0e10cSrcweir 2519cdf0e10cSrcweir // use three points since quadratic is imported as cubic 2520cdf0e10cSrcweir nPointCount += 3; 2521cdf0e10cSrcweir } 2522cdf0e10cSrcweir break; 2523cdf0e10cSrcweir } 2524cdf0e10cSrcweir 2525cdf0e10cSrcweir // #100617# not yet supported: elliptical arc 2526cdf0e10cSrcweir case 'A' : 2527cdf0e10cSrcweir case 'a' : 2528cdf0e10cSrcweir { 2529cdf0e10cSrcweir DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); 2530cdf0e10cSrcweir nPos++; 2531cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2532cdf0e10cSrcweir 2533cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2534cdf0e10cSrcweir { 2535cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2536cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2537cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2538cdf0e10cSrcweir Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); 2539cdf0e10cSrcweir Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); 2540cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2541cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2542cdf0e10cSrcweir } 2543cdf0e10cSrcweir break; 2544cdf0e10cSrcweir } 2545cdf0e10cSrcweir 2546cdf0e10cSrcweir default: 2547cdf0e10cSrcweir { 2548cdf0e10cSrcweir nPos++; 2549cdf0e10cSrcweir DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); 2550cdf0e10cSrcweir break; 2551cdf0e10cSrcweir } 2552cdf0e10cSrcweir } 2553cdf0e10cSrcweir } 2554cdf0e10cSrcweir 2555cdf0e10cSrcweir // alloc last poly (when points used) 2556cdf0e10cSrcweir if(nPointCount) 2557cdf0e10cSrcweir { 2558cdf0e10cSrcweir // #104076# If this partial polygon is closed, use one more point 2559cdf0e10cSrcweir // to represent that 2560cdf0e10cSrcweir if(mbIsClosed) 2561cdf0e10cSrcweir { 2562cdf0e10cSrcweir nPointCount++; 2563cdf0e10cSrcweir } 2564cdf0e10cSrcweir 2565cdf0e10cSrcweir pOuterSequence->realloc(nPointCount); 2566cdf0e10cSrcweir pOuterSequence++; 2567cdf0e10cSrcweir 2568cdf0e10cSrcweir if(pOuterFlags) 2569cdf0e10cSrcweir { 2570cdf0e10cSrcweir pOuterFlags->realloc(nPointCount); 2571cdf0e10cSrcweir pOuterFlags++; 2572cdf0e10cSrcweir } 2573cdf0e10cSrcweir } 2574cdf0e10cSrcweir 2575cdf0e10cSrcweir // set pointers back 2576cdf0e10cSrcweir pOuterSequence = maPoly.getArray(); 2577cdf0e10cSrcweir pOuterFlags = (IsCurve()) ? maFlag.getArray() : 0L; 2578cdf0e10cSrcweir awt::Point* pNotSoInnerSequence = 0L; 2579cdf0e10cSrcweir drawing::PolygonFlags* pNotSoInnerFlags = 0L; 2580cdf0e10cSrcweir sal_uInt32 nInnerIndex(0L); 2581cdf0e10cSrcweir 2582cdf0e10cSrcweir // prepare new loop, read points 2583cdf0e10cSrcweir nPos = 0; 2584cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2585cdf0e10cSrcweir 2586cdf0e10cSrcweir // #104076# reset closed flag for next to be started polygon 2587cdf0e10cSrcweir mbIsClosed = false; 2588cdf0e10cSrcweir 2589cdf0e10cSrcweir while(nPos < nLen) 2590cdf0e10cSrcweir { 2591cdf0e10cSrcweir bool bRelative(false); 2592cdf0e10cSrcweir 2593cdf0e10cSrcweir switch(aStr[nPos]) 2594cdf0e10cSrcweir { 2595cdf0e10cSrcweir case 'z' : 2596cdf0e10cSrcweir case 'Z' : 2597cdf0e10cSrcweir { 2598cdf0e10cSrcweir nPos++; 2599cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2600cdf0e10cSrcweir 2601cdf0e10cSrcweir // #104076# remember closed state of current polygon 2602cdf0e10cSrcweir mbIsClosed = true; 2603cdf0e10cSrcweir 2604cdf0e10cSrcweir // closed: add first point again 2605cdf0e10cSrcweir // sal_Int32 nX(pInnerSequence[0].X); 2606cdf0e10cSrcweir // sal_Int32 nY(pInnerSequence[0].Y); 2607cdf0e10cSrcweir // Imp_AddExportPoints(nX, nY, pInnerSequence, pInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2608cdf0e10cSrcweir 2609cdf0e10cSrcweir break; 2610cdf0e10cSrcweir } 2611cdf0e10cSrcweir 2612cdf0e10cSrcweir case 'm' : 2613cdf0e10cSrcweir { 2614cdf0e10cSrcweir bRelative = true; 2615cdf0e10cSrcweir } 2616cdf0e10cSrcweir case 'M' : 2617cdf0e10cSrcweir { 2618cdf0e10cSrcweir // #104076# end-process current poly 2619cdf0e10cSrcweir if(mbIsClosed) 2620cdf0e10cSrcweir { 2621cdf0e10cSrcweir if(pNotSoInnerSequence) 2622cdf0e10cSrcweir { 2623cdf0e10cSrcweir // closed: add first point again 2624cdf0e10cSrcweir sal_Int32 nX(pNotSoInnerSequence[0].X); 2625cdf0e10cSrcweir sal_Int32 nY(pNotSoInnerSequence[0].Y); 2626cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2627cdf0e10cSrcweir } 2628cdf0e10cSrcweir 2629cdf0e10cSrcweir // reset closed flag for next to be started polygon 2630cdf0e10cSrcweir mbIsClosed = false; 2631cdf0e10cSrcweir } 2632cdf0e10cSrcweir 2633cdf0e10cSrcweir // next poly 2634cdf0e10cSrcweir pNotSoInnerSequence = pOuterSequence->getArray(); 2635cdf0e10cSrcweir pOuterSequence++; 2636cdf0e10cSrcweir 2637cdf0e10cSrcweir if(pOuterFlags) 2638cdf0e10cSrcweir { 2639cdf0e10cSrcweir pNotSoInnerFlags = pOuterFlags->getArray(); 2640cdf0e10cSrcweir pOuterFlags++; 2641cdf0e10cSrcweir } 2642cdf0e10cSrcweir 2643cdf0e10cSrcweir nInnerIndex = 0L; 2644cdf0e10cSrcweir 2645cdf0e10cSrcweir nPos++; 2646cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2647cdf0e10cSrcweir 2648cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2649cdf0e10cSrcweir { 2650cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2651cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2652cdf0e10cSrcweir 2653cdf0e10cSrcweir if(bRelative) 2654cdf0e10cSrcweir { 2655cdf0e10cSrcweir nX += mnLastX; 2656cdf0e10cSrcweir nY += mnLastY; 2657cdf0e10cSrcweir } 2658cdf0e10cSrcweir 2659cdf0e10cSrcweir // set last position 2660cdf0e10cSrcweir mnLastX = nX; 2661cdf0e10cSrcweir mnLastY = nY; 2662cdf0e10cSrcweir 2663cdf0e10cSrcweir // calc transform and add point and flag 2664cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2665cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2666cdf0e10cSrcweir } 2667cdf0e10cSrcweir break; 2668cdf0e10cSrcweir } 2669cdf0e10cSrcweir 2670cdf0e10cSrcweir case 'l' : 2671cdf0e10cSrcweir { 2672cdf0e10cSrcweir bRelative = true; 2673cdf0e10cSrcweir } 2674cdf0e10cSrcweir case 'L' : 2675cdf0e10cSrcweir { 2676cdf0e10cSrcweir nPos++; 2677cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2678cdf0e10cSrcweir 2679cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2680cdf0e10cSrcweir { 2681cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2682cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2683cdf0e10cSrcweir 2684cdf0e10cSrcweir if(bRelative) 2685cdf0e10cSrcweir { 2686cdf0e10cSrcweir nX += mnLastX; 2687cdf0e10cSrcweir nY += mnLastY; 2688cdf0e10cSrcweir } 2689cdf0e10cSrcweir 2690cdf0e10cSrcweir // set last position 2691cdf0e10cSrcweir mnLastX = nX; 2692cdf0e10cSrcweir mnLastY = nY; 2693cdf0e10cSrcweir 2694cdf0e10cSrcweir // calc transform and add point and flag 2695cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2696cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2697cdf0e10cSrcweir } 2698cdf0e10cSrcweir break; 2699cdf0e10cSrcweir } 2700cdf0e10cSrcweir 2701cdf0e10cSrcweir case 'h' : 2702cdf0e10cSrcweir { 2703cdf0e10cSrcweir bRelative = true; 2704cdf0e10cSrcweir } 2705cdf0e10cSrcweir case 'H' : 2706cdf0e10cSrcweir { 2707cdf0e10cSrcweir nPos++; 2708cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2709cdf0e10cSrcweir 2710cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2711cdf0e10cSrcweir { 2712cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2713cdf0e10cSrcweir sal_Int32 nY(mnLastY); 2714cdf0e10cSrcweir 2715cdf0e10cSrcweir if(bRelative) 2716cdf0e10cSrcweir nX += mnLastX; 2717cdf0e10cSrcweir 2718cdf0e10cSrcweir // set last position 2719cdf0e10cSrcweir mnLastX = nX; 2720cdf0e10cSrcweir 2721cdf0e10cSrcweir // calc transform and add point and flag 2722cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2723cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2724cdf0e10cSrcweir } 2725cdf0e10cSrcweir break; 2726cdf0e10cSrcweir } 2727cdf0e10cSrcweir 2728cdf0e10cSrcweir case 'v' : 2729cdf0e10cSrcweir { 2730cdf0e10cSrcweir bRelative = true; 2731cdf0e10cSrcweir } 2732cdf0e10cSrcweir case 'V' : 2733cdf0e10cSrcweir { 2734cdf0e10cSrcweir nPos++; 2735cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2736cdf0e10cSrcweir 2737cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2738cdf0e10cSrcweir { 2739cdf0e10cSrcweir sal_Int32 nX(mnLastX); 2740cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2741cdf0e10cSrcweir 2742cdf0e10cSrcweir if(bRelative) 2743cdf0e10cSrcweir nY += mnLastY; 2744cdf0e10cSrcweir 2745cdf0e10cSrcweir // set last position 2746cdf0e10cSrcweir mnLastY = nY; 2747cdf0e10cSrcweir 2748cdf0e10cSrcweir // calc transform and add point and flag 2749cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2750cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 2751cdf0e10cSrcweir } 2752cdf0e10cSrcweir break; 2753cdf0e10cSrcweir } 2754cdf0e10cSrcweir 2755cdf0e10cSrcweir case 's' : 2756cdf0e10cSrcweir { 2757cdf0e10cSrcweir bRelative = true; 2758cdf0e10cSrcweir } 2759cdf0e10cSrcweir case 'S' : 2760cdf0e10cSrcweir { 2761cdf0e10cSrcweir nPos++; 2762cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2763cdf0e10cSrcweir 2764cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2765cdf0e10cSrcweir { 2766cdf0e10cSrcweir sal_Int32 nX1; 2767cdf0e10cSrcweir sal_Int32 nY1; 2768cdf0e10cSrcweir sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2769cdf0e10cSrcweir sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2770cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2771cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2772cdf0e10cSrcweir 2773cdf0e10cSrcweir if(bRelative) 2774cdf0e10cSrcweir { 2775cdf0e10cSrcweir nX2 += mnLastX; 2776cdf0e10cSrcweir nY2 += mnLastY; 2777cdf0e10cSrcweir nX += mnLastX; 2778cdf0e10cSrcweir nY += mnLastY; 2779cdf0e10cSrcweir } 2780cdf0e10cSrcweir 2781cdf0e10cSrcweir // set last position 2782cdf0e10cSrcweir mnLastX = nX; 2783cdf0e10cSrcweir mnLastY = nY; 2784cdf0e10cSrcweir 2785cdf0e10cSrcweir // calc transform for new points 2786cdf0e10cSrcweir Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2787cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2788cdf0e10cSrcweir 2789cdf0e10cSrcweir // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC 2790cdf0e10cSrcweir // and the Point X1,Y1 can be constructed by mirroring the point before it. 2791cdf0e10cSrcweir nX1 = nX2; 2792cdf0e10cSrcweir nY1 = nY2; 2793cdf0e10cSrcweir if(nInnerIndex) 2794cdf0e10cSrcweir { 2795cdf0e10cSrcweir awt::Point aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; 2796cdf0e10cSrcweir 2797cdf0e10cSrcweir if(nInnerIndex > 1) 2798cdf0e10cSrcweir { 2799cdf0e10cSrcweir awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; 2800cdf0e10cSrcweir nX1 = aPPrev1.X -(aPPrev2.X - aPPrev1.X); 2801cdf0e10cSrcweir nY1 = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); 2802cdf0e10cSrcweir } 2803cdf0e10cSrcweir 2804cdf0e10cSrcweir // set curve point to symmetric 2805cdf0e10cSrcweir pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SYMMETRIC; 2806cdf0e10cSrcweir } 2807cdf0e10cSrcweir 2808cdf0e10cSrcweir // add calculated control point 2809cdf0e10cSrcweir Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2810cdf0e10cSrcweir 2811cdf0e10cSrcweir // add new points and set flags 2812cdf0e10cSrcweir Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2813cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); 2814cdf0e10cSrcweir } 2815cdf0e10cSrcweir break; 2816cdf0e10cSrcweir } 2817cdf0e10cSrcweir 2818cdf0e10cSrcweir case 'c' : 2819cdf0e10cSrcweir { 2820cdf0e10cSrcweir bRelative = true; 2821cdf0e10cSrcweir } 2822cdf0e10cSrcweir case 'C' : 2823cdf0e10cSrcweir { 2824cdf0e10cSrcweir nPos++; 2825cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2826cdf0e10cSrcweir 2827cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2828cdf0e10cSrcweir { 2829cdf0e10cSrcweir sal_Int32 nX1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2830cdf0e10cSrcweir sal_Int32 nY1(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2831cdf0e10cSrcweir sal_Int32 nX2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2832cdf0e10cSrcweir sal_Int32 nY2(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2833cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2834cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2835cdf0e10cSrcweir 2836cdf0e10cSrcweir if(bRelative) 2837cdf0e10cSrcweir { 2838cdf0e10cSrcweir nX1 += mnLastX; 2839cdf0e10cSrcweir nY1 += mnLastY; 2840cdf0e10cSrcweir nX2 += mnLastX; 2841cdf0e10cSrcweir nY2 += mnLastY; 2842cdf0e10cSrcweir nX += mnLastX; 2843cdf0e10cSrcweir nY += mnLastY; 2844cdf0e10cSrcweir } 2845cdf0e10cSrcweir 2846cdf0e10cSrcweir // set last position 2847cdf0e10cSrcweir mnLastX = nX; 2848cdf0e10cSrcweir mnLastY = nY; 2849cdf0e10cSrcweir 2850cdf0e10cSrcweir // calc transform for new points 2851cdf0e10cSrcweir Imp_PrepareCoorImport(nX1, nY1, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2852cdf0e10cSrcweir Imp_PrepareCoorImport(nX2, nY2, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2853cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2854cdf0e10cSrcweir 2855cdf0e10cSrcweir // correct polygon flag for previous point 2856cdf0e10cSrcweir Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); 2857cdf0e10cSrcweir 2858cdf0e10cSrcweir // add new points and set flags 2859cdf0e10cSrcweir Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2860cdf0e10cSrcweir Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2861cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); 2862cdf0e10cSrcweir } 2863cdf0e10cSrcweir break; 2864cdf0e10cSrcweir } 2865cdf0e10cSrcweir 2866cdf0e10cSrcweir // #100617# quadratic beziers are imported as cubic 2867cdf0e10cSrcweir case 'q' : 2868cdf0e10cSrcweir { 2869cdf0e10cSrcweir bRelative = true; 2870cdf0e10cSrcweir } 2871cdf0e10cSrcweir case 'Q' : 2872cdf0e10cSrcweir { 2873cdf0e10cSrcweir nPos++; 2874cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2875cdf0e10cSrcweir 2876cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2877cdf0e10cSrcweir { 2878cdf0e10cSrcweir sal_Int32 nXX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2879cdf0e10cSrcweir sal_Int32 nYY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2880cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2881cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2882cdf0e10cSrcweir 2883cdf0e10cSrcweir if(bRelative) 2884cdf0e10cSrcweir { 2885cdf0e10cSrcweir nXX += mnLastX; 2886cdf0e10cSrcweir nYY += mnLastY; 2887cdf0e10cSrcweir nX += mnLastX; 2888cdf0e10cSrcweir nY += mnLastY; 2889cdf0e10cSrcweir } 2890cdf0e10cSrcweir 2891cdf0e10cSrcweir // set last position 2892cdf0e10cSrcweir mnLastX = nX; 2893cdf0e10cSrcweir mnLastY = nY; 2894cdf0e10cSrcweir 2895cdf0e10cSrcweir // calc transform for new points 2896cdf0e10cSrcweir Imp_PrepareCoorImport(nXX, nYY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2897cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2898cdf0e10cSrcweir 2899cdf0e10cSrcweir // calculate X1,X2 2900cdf0e10cSrcweir awt::Point aPPrev1 = (nInnerIndex) ? pNotSoInnerSequence[nInnerIndex-1] : pNotSoInnerSequence[0]; 2901cdf0e10cSrcweir sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); 2902cdf0e10cSrcweir sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); 2903cdf0e10cSrcweir sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); 2904cdf0e10cSrcweir sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); 2905cdf0e10cSrcweir 2906cdf0e10cSrcweir // correct polygon flag for previous point 2907cdf0e10cSrcweir Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); 2908cdf0e10cSrcweir 2909cdf0e10cSrcweir // add new points and set flags 2910cdf0e10cSrcweir Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2911cdf0e10cSrcweir Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2912cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); 2913cdf0e10cSrcweir } 2914cdf0e10cSrcweir break; 2915cdf0e10cSrcweir } 2916cdf0e10cSrcweir 2917cdf0e10cSrcweir // #100617# relative quadratic beziers are imported as cubic 2918cdf0e10cSrcweir case 't' : 2919cdf0e10cSrcweir { 2920cdf0e10cSrcweir bRelative = true; 2921cdf0e10cSrcweir } 2922cdf0e10cSrcweir case 'T' : 2923cdf0e10cSrcweir { 2924cdf0e10cSrcweir nPos++; 2925cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2926cdf0e10cSrcweir 2927cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2928cdf0e10cSrcweir { 2929cdf0e10cSrcweir sal_Int32 nXX; 2930cdf0e10cSrcweir sal_Int32 nYY; 2931cdf0e10cSrcweir sal_Int32 nX(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2932cdf0e10cSrcweir sal_Int32 nY(Imp_ImportNumberAndSpaces(0, aStr, nPos, nLen, rConv)); 2933cdf0e10cSrcweir 2934cdf0e10cSrcweir if(bRelative) 2935cdf0e10cSrcweir { 2936cdf0e10cSrcweir nX += mnLastX; 2937cdf0e10cSrcweir nY += mnLastY; 2938cdf0e10cSrcweir } 2939cdf0e10cSrcweir 2940cdf0e10cSrcweir // set last position 2941cdf0e10cSrcweir mnLastX = nX; 2942cdf0e10cSrcweir mnLastY = nY; 2943cdf0e10cSrcweir 2944cdf0e10cSrcweir // calc transform for new points 2945cdf0e10cSrcweir Imp_PrepareCoorImport(nX, nY, rObjectPos, rObjectSize, mrViewBox, bScale, bTranslate); 2946cdf0e10cSrcweir 2947cdf0e10cSrcweir // one more thing is known: the previous real point is PolygonFlags_SYMMETRIC 2948cdf0e10cSrcweir // and the Point X1,Y1 can be constructed by mirroring the point before it. 2949cdf0e10cSrcweir nXX = nX; 2950cdf0e10cSrcweir nYY = nY; 2951cdf0e10cSrcweir awt::Point aPPrev1 = pNotSoInnerSequence[0]; 2952cdf0e10cSrcweir 2953cdf0e10cSrcweir if(nInnerIndex) 2954cdf0e10cSrcweir { 2955cdf0e10cSrcweir aPPrev1 = pNotSoInnerSequence[nInnerIndex - 1]; 2956cdf0e10cSrcweir 2957cdf0e10cSrcweir if(nInnerIndex > 1) 2958cdf0e10cSrcweir { 2959cdf0e10cSrcweir awt::Point aPPrev2 = pNotSoInnerSequence[nInnerIndex - 2]; 2960cdf0e10cSrcweir nXX = aPPrev1.X -(aPPrev2.X - aPPrev1.X); 2961cdf0e10cSrcweir nYY = aPPrev1.Y -(aPPrev2.Y - aPPrev1.Y); 2962cdf0e10cSrcweir } 2963cdf0e10cSrcweir 2964cdf0e10cSrcweir // set curve point to smooth here, since length 2965cdf0e10cSrcweir // is changed and thus only c1 can be used. 2966cdf0e10cSrcweir pNotSoInnerFlags[nInnerIndex - 1] = drawing::PolygonFlags_SMOOTH; 2967cdf0e10cSrcweir } 2968cdf0e10cSrcweir 2969cdf0e10cSrcweir // calculate X1,X2 2970cdf0e10cSrcweir sal_Int32 nX1 = FRound((double)((nXX * 2) + aPPrev1.X) / 3.0); 2971cdf0e10cSrcweir sal_Int32 nY1 = FRound((double)((nYY * 2) + aPPrev1.Y) / 3.0); 2972cdf0e10cSrcweir sal_Int32 nX2 = FRound((double)((nXX * 2) + nX) / 3.0); 2973cdf0e10cSrcweir sal_Int32 nY2 = FRound((double)((nYY * 2) + nY) / 3.0); 2974cdf0e10cSrcweir 2975cdf0e10cSrcweir // correct polygon flag for previous point 2976cdf0e10cSrcweir Imp_CorrectPolygonFlag(nInnerIndex, pNotSoInnerSequence, pNotSoInnerFlags, nX1, nY1); 2977cdf0e10cSrcweir 2978cdf0e10cSrcweir // add new points and set flags 2979cdf0e10cSrcweir Imp_AddExportPoints(nX1, nY1, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2980cdf0e10cSrcweir Imp_AddExportPoints(nX2, nY2, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_CONTROL); 2981cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_SMOOTH); 2982cdf0e10cSrcweir } 2983cdf0e10cSrcweir break; 2984cdf0e10cSrcweir } 2985cdf0e10cSrcweir 2986cdf0e10cSrcweir // #100617# not yet supported: elliptical arc 2987cdf0e10cSrcweir case 'A' : 2988cdf0e10cSrcweir case 'a' : 2989cdf0e10cSrcweir { 2990cdf0e10cSrcweir DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (elliptical arc)!"); 2991cdf0e10cSrcweir nPos++; 2992cdf0e10cSrcweir Imp_SkipSpaces(aStr, nPos, nLen); 2993cdf0e10cSrcweir 2994cdf0e10cSrcweir while(nPos < nLen && Imp_IsOnNumberChar(aStr, nPos)) 2995cdf0e10cSrcweir { 2996cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2997cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2998cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 2999cdf0e10cSrcweir Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); 3000cdf0e10cSrcweir Imp_SkipNumberAndSpacesAndCommas(aStr, nPos, nLen); 3001cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 3002cdf0e10cSrcweir Imp_SkipDoubleAndSpacesAndCommas(aStr, nPos, nLen); 3003cdf0e10cSrcweir } 3004cdf0e10cSrcweir break; 3005cdf0e10cSrcweir } 3006cdf0e10cSrcweir 3007cdf0e10cSrcweir default: 3008cdf0e10cSrcweir { 3009cdf0e10cSrcweir nPos++; 3010cdf0e10cSrcweir DBG_ERROR("XMLIMP: non-interpreted tags in svg:d element (unknown)!"); 3011cdf0e10cSrcweir break; 3012cdf0e10cSrcweir } 3013cdf0e10cSrcweir } 3014cdf0e10cSrcweir } 3015cdf0e10cSrcweir 3016cdf0e10cSrcweir // #104076# end-process closed state of last poly 3017cdf0e10cSrcweir if(mbIsClosed) 3018cdf0e10cSrcweir { 3019cdf0e10cSrcweir if(pNotSoInnerSequence) 3020cdf0e10cSrcweir { 3021cdf0e10cSrcweir // closed: add first point again 3022cdf0e10cSrcweir sal_Int32 nX(pNotSoInnerSequence[0].X); 3023cdf0e10cSrcweir sal_Int32 nY(pNotSoInnerSequence[0].Y); 3024cdf0e10cSrcweir Imp_AddExportPoints(nX, nY, pNotSoInnerSequence, pNotSoInnerFlags, nInnerIndex++, drawing::PolygonFlags_NORMAL); 3025cdf0e10cSrcweir } 3026cdf0e10cSrcweir } 3027cdf0e10cSrcweir 3028cdf0e10cSrcweir // #87202# If it's a curve and it's closed the last point maybe too much 3029cdf0e10cSrcweir // and just exported since SVG does not allow special handling of same 3030cdf0e10cSrcweir // start and end point, remove this last point. 3031cdf0e10cSrcweir // Evtl. correct the last curve flags, too. 3032cdf0e10cSrcweir if(IsCurve() && IsClosed()) 3033cdf0e10cSrcweir { 3034cdf0e10cSrcweir // make one more loop over the PolyPolygon 3035cdf0e10cSrcweir pOuterSequence = maPoly.getArray(); 3036cdf0e10cSrcweir pOuterFlags = maFlag.getArray(); 3037cdf0e10cSrcweir sal_Int32 nOuterCnt(maPoly.getLength()); 3038cdf0e10cSrcweir 3039cdf0e10cSrcweir for(sal_Int32 a(0); a < nOuterCnt; a++) 3040cdf0e10cSrcweir { 3041cdf0e10cSrcweir // get Polygon pointers 3042cdf0e10cSrcweir awt::Point* pInnerSequence = pOuterSequence->getArray(); 3043cdf0e10cSrcweir drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray(); 3044cdf0e10cSrcweir sal_Int32 nInnerCnt(pOuterSequence->getLength()); 3045cdf0e10cSrcweir 3046cdf0e10cSrcweir while( nInnerCnt >= 2 3047cdf0e10cSrcweir && ((pInnerSequence + (nInnerCnt - 2))->X == (pInnerSequence + (nInnerCnt - 1))->X) 3048cdf0e10cSrcweir && ((pInnerSequence + (nInnerCnt - 2))->Y == (pInnerSequence + (nInnerCnt - 1))->Y) 3049cdf0e10cSrcweir && drawing::PolygonFlags_CONTROL != *(pInnerFlags + (nInnerCnt - 2))) 3050cdf0e10cSrcweir { 3051cdf0e10cSrcweir // remove last point from array 3052cdf0e10cSrcweir pOuterSequence->realloc(nInnerCnt - 1); 3053cdf0e10cSrcweir pOuterFlags->realloc(nInnerCnt - 1); 3054cdf0e10cSrcweir 3055cdf0e10cSrcweir // get new pointers 3056cdf0e10cSrcweir pInnerSequence = pOuterSequence->getArray(); 3057cdf0e10cSrcweir pInnerFlags = pOuterFlags->getArray(); 3058cdf0e10cSrcweir nInnerCnt = pOuterSequence->getLength(); 3059cdf0e10cSrcweir } 3060cdf0e10cSrcweir 3061cdf0e10cSrcweir // now evtl. correct the last curve flags 3062cdf0e10cSrcweir if(nInnerCnt >= 4) 3063cdf0e10cSrcweir { 3064cdf0e10cSrcweir if( pInnerSequence->X == (pInnerSequence + (nInnerCnt - 1))->X 3065cdf0e10cSrcweir && pInnerSequence->Y == (pInnerSequence + (nInnerCnt - 1))->Y 3066cdf0e10cSrcweir && drawing::PolygonFlags_CONTROL == *(pInnerFlags + 1) 3067cdf0e10cSrcweir && drawing::PolygonFlags_CONTROL == *(pInnerFlags + (nInnerCnt - 2))) 3068cdf0e10cSrcweir { 3069cdf0e10cSrcweir awt::Point aPrev = *(pInnerSequence + (nInnerCnt - 2)); 3070cdf0e10cSrcweir awt::Point aCurr = *pInnerSequence; 3071cdf0e10cSrcweir awt::Point aNext = *(pInnerSequence + 1); 3072cdf0e10cSrcweir ::basegfx::B2DVector aVec1(aPrev.X - aCurr.X, aPrev.Y - aCurr.Y); 3073cdf0e10cSrcweir ::basegfx::B2DVector aVec2(aNext.X - aCurr.X, aNext.Y - aCurr.Y); 3074cdf0e10cSrcweir bool bSameLength(false); 3075cdf0e10cSrcweir bool bSameDirection(false); 3076cdf0e10cSrcweir 3077cdf0e10cSrcweir // get vector values 3078cdf0e10cSrcweir Imp_CalcVectorValues(aVec1, aVec2, bSameLength, bSameDirection); 3079cdf0e10cSrcweir 3080cdf0e10cSrcweir // set correct flag value 3081cdf0e10cSrcweir if(bSameDirection) 3082cdf0e10cSrcweir { 3083cdf0e10cSrcweir if(bSameLength) 3084cdf0e10cSrcweir { 3085cdf0e10cSrcweir // set to PolygonFlags_SYMMETRIC 3086cdf0e10cSrcweir *pInnerFlags = drawing::PolygonFlags_SYMMETRIC; 3087cdf0e10cSrcweir *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SYMMETRIC; 3088cdf0e10cSrcweir } 3089cdf0e10cSrcweir else 3090cdf0e10cSrcweir { 3091cdf0e10cSrcweir // set to PolygonFlags_SMOOTH 3092cdf0e10cSrcweir *pInnerFlags = drawing::PolygonFlags_SMOOTH; 3093cdf0e10cSrcweir *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_SMOOTH; 3094cdf0e10cSrcweir } 3095cdf0e10cSrcweir } 3096cdf0e10cSrcweir else 3097cdf0e10cSrcweir { 3098cdf0e10cSrcweir // set to PolygonFlags_NORMAL 3099cdf0e10cSrcweir *pInnerFlags = drawing::PolygonFlags_NORMAL; 3100cdf0e10cSrcweir *(pInnerFlags + (nInnerCnt - 1)) = drawing::PolygonFlags_NORMAL; 3101cdf0e10cSrcweir } 3102cdf0e10cSrcweir } 3103cdf0e10cSrcweir } 3104cdf0e10cSrcweir 3105cdf0e10cSrcweir // switch to next Polygon 3106cdf0e10cSrcweir pOuterSequence++; 3107cdf0e10cSrcweir pOuterFlags++; 3108cdf0e10cSrcweir } 3109cdf0e10cSrcweir } 3110cdf0e10cSrcweir } 3111cdf0e10cSrcweir } 3112cdf0e10cSrcweir 3113cdf0e10cSrcweir // eof 3114